Generics 用于切片的泛型remove()函数

Generics 用于切片的泛型remove()函数,generics,go,slice,Generics,Go,Slice,我有3个切片(foo、bar、baz),每个切片都填充了不同类型的结构。为了删除一些样板代码,我想创建一个通用的remove(slice,struct)slice函数。与标准中提供的append()相反 没有一个结构是指针,因此没有必要将其置零。我曾想过使用接口{}来获得所需的结果,但没有效果。当前实现使用一个类型开关,然后有一个近复制粘贴的remove()(下面链接中的示例)从切片中删除。随着我继续扩展这个项目,它将成为更多的样板 正在尝试的示例: 如果它简单且易于实现。我想象它已经存在于标

我有3个切片(foo、bar、baz),每个切片都填充了不同类型的结构。为了删除一些样板代码,我想创建一个通用的remove(slice,struct)slice函数。与标准中提供的append()相反

没有一个结构是指针,因此没有必要将其置零。我曾想过使用接口{}来获得所需的结果,但没有效果。当前实现使用一个类型开关,然后有一个近复制粘贴的remove()(下面链接中的示例)从切片中删除。随着我继续扩展这个项目,它将成为更多的样板

正在尝试的示例:

如果它简单且易于实现。我想象它已经存在于标准中了。然而,从经验丰富的专业人士那里得到建议,告诉他们我正在尝试做的事情是否有可能,这并没有什么坏处


感谢您抽出时间。

我查看了您的示例代码及其错误。有关
接口片的更多信息,请参阅本节和


泛型实现有点复杂,您可以使用基于类型的实现。然而,基于类型的实现带来了更多的样板代码/重复代码

您需要按照评论中提到的@stephen weinberg使用该软件包


所以最好的出发点是;尝试这个库并浏览库代码库,自己实现。这个库使用反射

尝试使围棋通用化是新围棋开发者的一大陷阱。停止您正在保存:

是的,在通用语言中,您可以将这五行代码打包成一个漂亮的stdlib方法,但Go不是通用语言。尝试用反射来实现这一点很慢,但这并不是避免它的原因。反射非常复杂。很难把它弄对。你将花费更多的时间来计算
和追踪奇怪的角落案例,而不是12次重写这五行代码(包括修复意外剪切/粘贴错误的时间,以及一次搞乱
i--
)。写下来就行了

只需编写代码就可以决定平等的含义。它让您决定是在第一次匹配时停止搜索,还是继续浏览整个列表。它让你做这个程序需要的事情,而不是专注于某个通用程序将来可能需要的事情

我喜欢泛型编程。没有什么比在哈斯克尔创造一个优雅的折叠更让我高兴的了。但这不是办法。在Go中,您通常只需编写代码,保持简单明了,然后继续前进

Andy提出了一个很好的观点,如果您必须经常这样做,
list
可能是一个更好的数据结构。我经常发现,当我有三种类型时,它们似乎都有并行方法,结果它们都应该是单个结构的一部分(你真的需要单独的列表吗?),但在任何情况下,远离反射,除非你有一个非常特殊的问题,你真正的意思是“任何东西”,而不是“这些事情中的一个。”


(值得注意的是,您调用了
append()
。我认为不可能编写
append())
在Go中。这就是为什么它必须是语言的一部分,而不是stdlib函数。当我开始在Go中工作时,我认为这是语言中的一个重大缺陷。我在Go中工作的时间越长,我就越觉得它不重要。你只需编写代码,然后继续。)

您需要为此使用反射。它不是类型安全的,而且速度较慢。可能吗?是的。好主意?几乎肯定不是,原因已经提到:它将非常缓慢。看起来我将熟悉反射,以便运行一些关于效率的基准。我可能会选择退出并返回到boilerplatE版本一旦我运行基准。谢谢你的反馈。你需要索引到这些片断或者仅仅附加、删除、迭代吗?如果你不需要随机访问,你可能想考虑一个不同的数据结构,比如链表(例如)。这是最好的答案。我不认为自己是一个普通的程序员,C是我的第一语言。当我看到这个机会的时候,我想尝试一下。我决定把一些派生类绑定到基类中去消除一些样板并继续这个项目。这是它的特点,但最好是亲吻和更接近“走的方式”的东西!谢谢你的有用的答案。这里有一个重要的教训:走也不是面向对象的。所以如果你想“类”,特别是“基”“同学们,你们也在战斗。Go是关于接口的,但它没有继承性。也就是说,研究嵌入。这是一个关键的Go特性,大多数新手都不知道,并且完全改变了您构造类型的方式。(同时阅读所有的“有效围棋”。这是对“围棋之路”最好的介绍之一。)我感谢阅读材料和指导,让我朝着更正确的方向前进。我会重读/研究它,让它完全融入其中。再次感谢你的努力,罗布!
Function input: []slices, struct
Expected output: 
    Modified (removed struct) []slices if struct is found
    Or, Unmodified []slices if it isn't.
for i := len(foos) - 1; i >= 0; i-- {
    if foos[i] == foo1 {
        foos = append(foos[:i], foos[i+1:]...)
    }
}