Go语言空接口的一个问题——已解决(Go不可寻址)
前提知识
Go语言的空接口可以很方便地实现多态,它可以存储任意类型的值,那我们如何获取其存储的具体数据呢?
想要判断空接口中的值这个时候就可以使用类型断言,其语法格式:
1 | x.(T) |
其中:
- x:表示类型为
interface{}
的变量 - T:表示断言
x
可能是的类型。
该语法返回两个参数,第一个参数是x
转化为T
类型后的变量,第二个值是一个布尔值,若为true
则表示断言成功,为false
则表示断言失败。
问题描述
话不多说,上例子
1 | package main |
这里定义了一个空接口i和一个结构体element
我把一个element变量赋给i,可以通过类型断言得到结构体的字段值
但是没办法通过断言直接修改i的值
尝试了一下创建一个新的结构体,把新的结构体赋给i是可以的
思考
又去翻阅了一下资料,.(T)
会尝试把空接口转换成T
类型,这里i.(element)
应该是一个转换之后的element
类型的匿名结构体,按理说对这个匿名结构体的成员进行赋值应该是可以的(虽然没有变量接收这个值),但是编译器会报一个错误。
按照类型赋值的语法来说应该是没问题的,那为什么报错呢?这里不太理解,个人感觉是为了避坑所以直接不允许这样操作。
20210531更新
通过Go语言群里老大哥的指点,找到问题所在了。
Golang不可寻址
不可寻址, 指的是不能通过&获得其地址。不能获得其地址,自然无法修改它的值。
golang中不能寻址的可以总结为:不可变的,临时结果和不安全的。只要符合其中任何一个条件,它就是不可以寻址的。
具体为:
常量的值。
基本类型值的字面量
算术操作的结果值
对各种字面量的索引表达式和切片表达式的结果值,不过有一个例外,对切片字面量的索引结果值却是可寻址的。
对字符串变量的索引表达式和切片表达式的结果值。
对字典变量的索引表达式的结果值。
函数字面量和方法字面量,以及对它们的调用表达式的结果值。
结构体字面量的字段值,也就是对结构体字面量的选择表达式的结果值。
类型转换表达式的结果值。
类型断言表达式的结果值。
接收表达式的结果值。
附一个demo连接:https://github.com/hyper0x/Golang_Puzzlers/blob/master/src/puzzlers/article15/q1/demo35.go