我想表达一个可以取任何切片的函数。我想我可以这样做:
func myFunc(list []interface{}) {
for _, i := range list {
...
some_other_fun(i)
...
}
}
where some_other_fun(..)
本身需要一个interface{}
类型。然而,这不起作用,因为你无法通过[]DEFINITE_TYPE
as []interface{}
. See: https://golang.org/doc/faq#convert_slice_of_interface https://golang.org/doc/faq#convert_slice_of_interface其中注意到 []interface{} 的表示是不同的。这个答案总结了原因,但针对的是接口指针而不是接口切片,但原因是相同的:为什么我不能将 *Struct 分配给 *Interface? https://stackoverflow.com/questions/13511203/why-cant-i-assign-a-struct-to-an-interface.
上面的 golang.org 链接提供的建议建议从DEFINITE_TYPE
片。然而,在我想要调用这个函数的代码中的任何地方都这样做并不实际(这个函数本身只是为了缩写 9 行代码,但这 9 行在我们的代码中出现得相当频繁)。
在每种情况下,我想调用该函数,我都会传递一个[]*DEFINITE_TYPE
我一开始认为这会更容易抽象,直到我再次发现为什么我不能将 *Struct 分配给 *Interface? https://stackoverflow.com/questions/13511203/why-cant-i-assign-a-struct-to-an-interface(也在上面链接)。
此外,每次我想调用该函数时,它都会使用不同的DEFINITE_TYPE
因此,为 n 个类型实现 n 个示例不会为我节省任何代码行或使我的代码更清晰(恰恰相反!)。
令人沮丧的是,我无法做到这一点,因为这 9 行在我们的代码中是惯用的,而且输入错误很容易引入错误。我真的很缺少泛型。难道真的没有办法了吗?!!
在您提供的情况下,您必须将切片创建为interface
e.g. s := []interface{}{}
。此时,您实际上可以将任何您想要的类型放入切片中(甚至是混合类型)。但是这样你就必须进行各种类型断言,一切都会变得非常糟糕。
解组器常用的另一种技术是这样的定义:
func myFunc(list interface{})
因为切片适合interface
,您确实可以将常规切片传递到其中。您仍然需要在中进行一些验证和类型断言myFunc
,但是您可以对整个列表类型进行单个断言,而不必担心可能包含混合类型的列表。
不管怎样,由于是静态类型语言,您最终必须知道通过断言传入的类型。事情就是这样。在你的情况下,我可能会使用上面的 func 签名,然后使用类型开关来处理不同的情况。请参阅此文档https://new Fivefour.com/golang-interface-type-assertions-switch.html https://newfivefour.com/golang-interface-type-assertions-switch.html
所以,像这样:
func myFunc(list interface{}) {
switch v := list.(type) {
case []string:
// do string thing
case []int32, []int64:
// do int thing
case []SomeCustomType:
// do SomeCustomType thing
default:
fmt.Println("unknown")
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)