Types 为什么[]字符串不能转换为golang中的[]接口{}
我发现它很奇怪,为什么[]字符串不能转换为[]接口{} 我认为这应该是可能的,因为:Types 为什么[]字符串不能转换为golang中的[]接口{},types,interface,go,Types,Interface,Go,我发现它很奇怪,为什么[]字符串不能转换为[]接口{} 我认为这应该是可能的,因为: 它们都是切片 []字符串的每个元素都是字符串,当然是接口{} 但在下面的示例中,这将是一个编译错误 func f(args ...interface{}){ } s := []string{"ssd", "rtt"} f(s...) 为什么语言不能自动完成转换?因为[]字符串和[]接口{}在内存中的布局不同。当您意识到接口{}变量需要知道它包含的值的类型时,这一点就很明显了 对于[]字符串切片,支持数组只需
func f(args ...interface{}){
}
s := []string{"ssd", "rtt"}
f(s...)
为什么语言不能自动完成转换?因为
[]字符串
和[]接口{}
在内存中的布局不同。当您意识到接口{}
变量需要知道它包含的值的类型时,这一点就很明显了
对于[]字符串
切片,支持数组只需要保存单个字符串。对于[]接口{}
片,您既有类型信息,也有字符串值(因为字符串大于单个内存字,所以指向字符串值的指针)。因此,从一种类型转换到另一种类型需要复制数据
Go自动执行转换会让人感到困惑,因为这会使代码难以推理。例如,一个函数调用
f(s)
可以修改片s
中的字符串,如果它被声明为采用[]字符串
参数,但如果它被声明为采用[]接口{}
参数,则不能修改。片基本上只是对底层数组、起始指针、长度和容量的引用。因此,如果可能的话,请考虑以下内容:
sliceOfStrings := []string{"one", "two", "three"}
// prints ONE TWO THREE
for i := range sliceOfStrings {
fmt.Println(strings.ToUpper(sliceOfStrings[i]))
}
// imagine this is possible
var sliceOfInterface = []interface{}(sliceOfStrings)
// since it's array of interface{} now - we can do anything
// let's put integer into the first position
sliceOfInterface[0] = 1
// sliceOfStrings still points to the same array, and now "one" is replaced by 1
fmt.Println(strings.ToUpper(sliceOfStrings[0])) // BANG!
Java和C#中存在此问题。实际上,这种情况很少发生,但仍然存在。考虑到Go中没有像int32->int64这样的自动类型转换,如果您真的想将[]字符串作为[]接口{}发送,那么就必须创建[]接口{}副本。这样就不会有什么意外了——你明确地写了它,你知道你在做什么。如果函数将修改[]接口{},则不会损害原始[]字符串。Golang数组不支持协方差-请参阅常见问题解答中的说明。阅读golang.org上提供的文档不可过分推荐。重复