如何解决地图、切片或通道类型的类型安全
我想知道为什么这段代码在 go 中编译。我预计会出现编译器错误,例如字符串:
package main
import (
"fmt"
)
type myMap map[string]int
type mySlice []int
type myChan chan int
type myString string
func main() {
var mm myMap
var m map[string]int
m = mm // fine,but expected compiler error
var ms mySlice
var s []int
s = ms // same with slices
var mc myChan
var c chan int
c = mc // or channels
var mstr myString
var str string
// str = mstr // error,as expected
fmt.Printf("%T %T %T %T %T %T %T %T\n",mm,m,ms,s,mc,c,mstr,str)
}
Playground
为什么我在使用那些特殊的“引用类型”映射、切片和 chan 时不会出现类型不匹配错误?
解决方法
在前两种情况下您不会遇到编译时错误,因为语言规范允许这些赋值。
在赋值中,每个值都必须是 assignable 到它被赋值的操作数的类型...
值 x
可分配给 T
类型的 variable(“x
可分配给 T
”)如果以下条件之一适用:
-
x
的类型与T
相同。 x
的类型V
和T
具有相同的 underlying types 并且至少V
或T
之一不是defined 类型。-
T
是接口类型,x
implementsT
。 -
x
是双向通道值,T
是通道类型,x
的类型V
和T
具有相同的元素类型,并且在V
或T
中的至少一个不是定义的类型。 -
x
是预先声明的标识符nil
,T
是指针、函数、切片、映射、通道或接口类型。 -
x
是类型为T
的值的无类型 constant representable。
强调规则适用于您的前 2 个案例。但是,它不适用于您的最后一种情况,因为 string
和 myString
都是已定义的类型。没有任何规则适用于您的最后一种情况。
根据语言规范:
x 的类型 V 和 T 具有相同的底层类型,并且 V 或 T 中至少有一个不是定义的类型。
myMap
是一个定义的类型,但 map[string]int
不是,而且由于底层类型是相同的,所以赋值是有效的。
string
是一个定义的类型,所以分配给另一个定义的类型不起作用。您必须明确复制。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。