假设我想写一个函数,在切片中查找一个值
我本能地想写:
func find(s []interface{}, f func(interface{})bool) int {
for i, item := range s {
if f(item) {
return i
}
}
return -1
}
字符串
但是我不能用Go来做这个。我可以有一个接口,
Len() int
Value(int) interface{}
...
型
这是可行的,但在我的真实的代码中,事情要复杂得多(我需要做切片[from:end]等),追加,.等,如果我在一个接口中重新定义所有这些,我最终会有很多代码。有更好的方法吗?
4条答案
按热度按时间raogr8fs1#
你可以使用反射。我为一个项目写了这个函数,请随意使用它:
字符串
hkmswyz62#
鉴于这里的答案都不是在go添加泛型之前写的,我将添加如何在go1.18+中实现它
但是请注意,从go1.21开始,有一个
slices
包包含许多有用的通用切片函数。这是直接来自标准库的
IndexFunc
的实现字符串
注意函数是如何使用类型参数
[S ~[]E, E any]
而不仅仅是S []any
的。区别在于go中切片的类型。就像你可以将一种类型的切片Assert为另一种类型的切片,即使可以Assert元素(例如,即使int满足any
,[]int{}.([]any)
也是无效的),如果S
被限制为[]any
,则可以使用[]int
作为S
类型的参数。相反,它使用
S ~[]E
将S
约束为具有E
类型元素的切片,其中E
可以是任何类型。此外,这允许函数单独使用元素类型,您可以通过第二个参数看到:f func(E) bool
。iyzzxitl3#
如果您有预定义类型,如
[]int
或[]string
,但不想转换为[]interface{}
,请参阅以下工作示例代码(不使用reflect
):字符串
或者你可以使用
reflect
,像这样的工作示例代码:型
产出:
型
我希望这能帮上忙。
kdfy810k4#
我认为,如果你想拥有任意值的切片,使用那种
find
函数,并有可能进行标准的[]
重新切片,也许最好的方法是用另一个结构体封装你的interface{}
。字符串
和使用
型
并让
f
函数处理interface{}
比较/类型转换。