切片的通用remove()函数

时间:2017-07-13 18:15:50

标签: generics go slice

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

所有结构都不是指针,因此不需要对它们进行任何操作。我已经调整了使用 interface {} 来获得所需结果无效的想法。当前实现使用Type Switch,然后使用近似复制粘贴的remove()(在下面的playground链接中的示例)从切片中删除。随着我继续扩展该项目,它将成长为更多样板。

正在尝试的例子: 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.

如果它简单易行。我想象它已经存在于标准中。然而,从更多经验丰富的专业人士那里得到的建议,如果我试图做的事情是可能的话,从来都不会受到伤害。

谢谢你的时间。

2 个答案:

答案 0 :(得分:4)

尝试使Go泛型是新Go开发人员的一大陷阱。停止。您正在保存five of lines of code

for i := len(foos) - 1; i >= 0; i-- {
    if foos[i] == foo1 {
        foos = append(foos[:i], foos[i+1:]...)
    }
}

是的,在通用语言中,您可以将这五行包装到一个不错的stdlib方法中,但Go不是通用语言。试图用反射来做这个很慢,但这不是避免它的原因。反思非常复杂。很难做到对。你花费更多的时间来找出Value并追逐奇怪的角落情况,而不是花费12次重写这五行代码(包括修复你不小心剪掉/粘贴错误的时间,有一次你陷入困境i--)。写下来吧。

只需编写代码,您就可以决定平等意味着什么。它允许您决定是在第一场比赛中停止搜索,还是继续浏览整个列表。它可以让你完成这个程序所需要的东西,而不是专注于某些通用程序有朝一日可能需要的东西。

我喜欢通用编程。几乎没有什么比在Haskell中创造优雅的折叠更让我开心。但这不是Go的方式。在Go中,您通常只需编写代码,保持简单明了,然后继续。

Andy指出,如果你必须做很多事情,list可能是一个更好的数据结构。而且我经常发现当我有三种类型似乎都有并行方法时,事实证明它们应该都是单个结构的一部分(你真的需要单独的列表吗?)但无论如何,请保持远离反思,除非你有一个非常专业的问题,你真正的意思是“任何事情”,而不是“其中一个简短的事情。”

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

答案 1 :(得分:1)

我查看了您的示例代码及其错误。要详细了解interface slice,请参阅此Go wikiSliceTricks

通用实现有点复杂,您可以使用基于类型的实现。但是,基于类型的实现会在样板/重复上带来更多代码。

您需要使用reflect软件包作为评论中提到的@ stephen-weinberg的目的。

所以最好的出发点是;试试这个库github.com/anzhihun/generic并浏览库代码库,自己实现。该库使用反射。