我有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.
如果它简单易行。我想象它已经存在于标准中。然而,从更多经验丰富的专业人士那里得到的建议,如果我试图做的事情是可能的话,从来都不会受到伤害。
谢谢你的时间。
答案 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 wiki和SliceTricks。
通用实现有点复杂,您可以使用基于类型的实现。但是,基于类型的实现会在样板/重复上带来更多代码。
您需要使用reflect软件包作为评论中提到的@ stephen-weinberg的目的。
所以最好的出发点是;试试这个库github.com/anzhihun/generic并浏览库代码库,自己实现。该库使用反射。