我有3片(fos,酒吧,巴兹),每个都填充了不同类型的结构。为了删除一些样板代码,我想创建一个通用的删除(切片,结构)切片函数。类似于标准中提供的append()的反义词。
没有一个结构是指针,因此没有必要将其置零。我曾经想过使用接口{}来获得想要的结果,但没有效果。当前实现使用一个类型开关,然后有一个近复制粘贴的remove()(下面链接中的示例)从切片中删除。随着我继续扩展这个项目,它将成为更多的样板。
正在尝试的示例:https://play.golang.org/p/9UPRIIp5M2
Function input: []slices, struct
Expected output:
Modified (removed struct) []slices if struct is found
Or, Unmodified []slices if it isn't.
如果它简单且易于实现。我想象它已经存在于标准中了。然而,从经验丰富的专业人士那里得到建议,告诉他们我正在尝试做的事情是否有可能,这并没有什么坏处。
谢谢你的时间。
我看了你的示例代码及其错误。要了解更多关于接口切片的信息,请参考Go wiki和SliceTricks。
泛型实现有点复杂,您可以使用基于类型的实现。然而,基于类型的实现带来了更多样板/重复的代码。
您需要按照评论中提到的@stephen weinberg使用reflect软件包。
所以最好的出发点是;试试这个github库。com/anzhihun/generic并遍历库代码库,自行实现。这个库使用反射。
试图使围棋通用化是新围棋开发者的一大陷阱。停止您正在保存五行代码:
for i := len(foos) - 1; i >= 0; i-- {
if foos[i] == foo1 {
foos = append(foos[:i], foos[i+1:]...)
}
}
是的,在通用语言中,您可以将这五行代码打包成一个漂亮的stdlib方法,但Go不是通用语言。尝试用反射来实现这一点很慢,但这并不是避免它的原因。反射非常复杂。很难把它弄对。你将花费更多的时间来计算值
和追踪奇怪的角落案例,而不是12次重写这五行代码(包括修复意外剪切/粘贴错误的时间,以及一次搞乱i--
)。写下来就行了。
编写代码可以让您决定平等的含义。它让你决定是在第一次匹配时停止搜索,还是继续浏览整个列表。它让你做这个程序需要的事情,而不是关注某个通用程序有一天可能需要的东西。
我喜欢泛型编程。没有什么比在哈斯克尔创造一个优雅的折叠更让我高兴的了。但这不是办法。在Go中,您通常只需编写代码,保持简单明了,然后继续前进。
Andy提出了一个很好的观点,如果您必须经常这样做,list
可能是一个更好的数据结构。我经常发现,当我有三种似乎都有并行方法的类型时,它们都应该是单个结构的一部分(这里真的需要单独的列表吗?)但在任何情况下,都要远离反思,除非你有一个非常特殊的问题,你真正的意思是“任何事情”,而不是“这些事情中的一个”
(值得注意的是,您调用append()
。我认为在Go中写append()
是不可能的。这就是为什么它必须是语言的一部分,而不是stdlib函数。当我开始学习围棋时,我认为这是语言中的一个重大缺陷。我在围棋上工作的时间越长,就越发现它不那么重要。你只需编写代码,然后继续前进。)
同样的规则也可以适用于函数:在使用前给出 <T> 后,类型 T 就变成了泛型。 使用泛型函数有时需要显式地指明类型参量。这种可能的情况包括,调用返回类型是泛型的函数,或者编译器没有足够的信息来推导类型参量。 函数调用使用显式指定的类型参量,如下所示: fun::<A, B, ...>(). struct A; // 具体类型 `A`。 struct S(A); //
问题内容: 我目前正在努力完成出色的“围棋之旅”。我使用以下解决方案完成了其中一项练习(#45): 我不明白为什么我必须使用两次该类型的语句(请参见摘要中的注释)。这似乎是多余的,但我不知道该怎么做。 问题答案: Go中没有其他方法可以做到这一点。 是的,我同意这很冗长,但有必要。第二个make()语句完全独立于第一个。可以争论的是,编译器应该能够从推断类型,但此时还不行。 另一点:如果在第二种情
问题内容: 如果我有一个像这样的抽象类: 还有一些从Item派生的类是这样的: 我不明白为什么我不能使用泛型调用构造函数: 我知道可以有一个没有构造函数的类型,但是这种情况是不可能的,因为Pencil具有没有参数的构造函数,而Item是抽象的。但是我从eclipse中得到了这个错误: 无法实例化 我不明白为什么的 T类型 ,以及如何避免这种情况? 问题答案: 无法使用Java类型系统来强制类层次结
问题内容: 我正在学习中,文档和交互式课程说,空可以容纳任何类型,因为它不需要其他实现的方法。 举个例子: …将打印出来… 因此,我想我的问题是这是实现通用函数的方法,还是还有另一种更合适的方法来实现它们。 问题答案: Go范式通常是通过在非空接口中实现行为来避免这种情况。例如,假设您要打印特定于类型的格式的内容: 或者,您可以为知道如何进行字符串自身设置的接口定义一个接口(该接口在库中以形式存在
我不想为每个类型T编写这个方法只是为了调用getMessage()并将其传递给下一个方法。 有可能写出这样的方法吗?我只想访问ConstraintViolation接口的方法,这些方法不依赖于类型T(如字符串getMessage())。
泛型函数定义 泛型函数可以用于任何类型. 这里是上面提到的swapTwoInts(_:, _:)函数的泛型版本, 叫做swapTwoValues(_:_:) func swapTwoValues<T>(_ a: inout T, _ b: inout T) { let temporaryA = a a = b b = temporaryA } 上面的s