为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 []string 不能在 golang 中转换为 []interface{}

为什么 []string 不能在 golang 中转换为 []interface{}

Go
白衣非少年 2021-07-08 14:05:31
我发现它很奇怪,为什么 []string 不能转换为 []interface{} ?我认为应该是可能的,因为:它们都是切片[]string的每一个元素都是字符串,当然是interface{}但在下面的例子中,这将是一个编译错误func f(args ...interface{}){}s := []string{"ssd", "rtt"}f(s...)为什么语言不能自动完成转换?
查看完整描述

2 回答

?
慕运维8079593

TA贡献1876条经验 获得超5个赞

Slice 基本上只是对底层数组、起始指针、长度和容量的引用。因此,如果可能的话,请考虑以下事项:


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 这样的自动类型转换,如果你真的想将 []string 作为 []interface{} 发送,你被迫创建一个 []interface{} 副本是有道理的。这样就不会令人惊讶了 - 你明确地写了它,你知道你在做什么。如果函数会修改 []interface{} - 它不会伤害原始的 []string。


查看完整回答
反对 回复 2021-07-19
?
郎朗坤

TA贡献1921条经验 获得超9个赞

因为[]string[]interface{}有不同的内存布局。当您意识到一个interface{}变量需要知道它所包含的值的类型时,这一点很明显。

对于[]string切片,后备数组只需要保存单个字符串。对于[]interface{}切片,您已经获得了类型信息和字符串值(嗯,指向字符串值的指针,因为字符串大于内存中的单个字)。因此,从一种类型转换为另一种类型将涉及复制数据。

Go 自动执行转换会令人困惑,因为它会使代码推理变得困难。例如,函数调用f(s)可以修改切片中的字符串,s如果它被声明为接受一个[]string参数,但如果它被声明为接受一个参数,则不能[]interface{}


查看完整回答
反对 回复 2021-07-19
  • 2 回答
  • 0 关注
  • 812 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信