在以下代码片段中,最后三个赋值产生了编译错误:package maintype ( Foo []float64 Baz [2]float64 Meh map[string]string Faq chan int Tet func() Hue interface{} Tai bool Foz string Bar float64)func main() { var ( foo Foo = []float64{1, 2, 3} _ []float64 = foo baz Baz = [...]float64{1, 2} _ [2]float64 = baz meh Meh = make(map[string]string) _ map[string]string = meh faq Faq = make(chan int) _ chan int = faq tet Tet = func() { return } _ func() = tet hue Hue = "Hello, World" _ interface{} = hue tai Tai = true _ bool = tai // error foz Foz = "Hello, World" _ string = foz // error bar Bar = 1 _ float64 = bar // error )}这意味着,在这个例子中,只有 bools、strings 和 floats 是不可分配的。原因可以在规范中找到:在以下任一情况下,值 x 可分配给 T 类型的变量(“x 可分配给 T”):[...]x 的类型 V 和 T 具有相同的基础类型,并且 V 或 T 中至少有一个不是命名类型。[...](Go 规范:可分配性)和[...] 命名类型由(可能限定的)类型名称指定;未命名类型使用类型文字指定,该类型文字从现有类型组成新类型。[...]( Go 规格: 类型)结合这一点,别名assign不起作用的原因是因为命名了后三种情况的类型。这样就违反了规则:两个命名类型是赋值的一部分。现在我的实际问题:为什么不允许将别名字符串/bool/numeric 分配给实际的 string/bool/numeric,而不是像切片和数组这样的类型?缺少这条规则会导致什么样的问题?将字符串指定为命名类型会导致哪些问题?
1 回答
料青山看我应如是
TA贡献1772条经验 获得超8个赞
可赋值性规则意味着您有时必须在命名类型之间进行转换以明确表示“是的,我的意思是string
将其用作 a Foo
”,即使它们共享相同的基础类型。这与以下内容相关os.FileMode
:它是下面的数字,但类型检查将防止您意外将其传递给采用无关foo uint32
. (可分配性规则也影响函数调用:您可以传递可分配给参数类型的任何类型的参数。)
通常,这意味着如果您对底层类型有不同的、可能容易混淆的用途,您可以为它们分配不同的名称。像:底层类型[][4]float32
可以正当的拥有RGBASlice
,HSVASlice
以及XYZWSlice
类型名称分配。您不能将 a 传递RGBASlice
给需要XYZWSlice
. 但是,所有这些都可以透明地传递给不关心数字含义的事物,例如,如果您有一些通用的矢量数学例程。
因此,从广义上讲,通过强制您在命名类型之间进行转换,Go 可以帮助您区分在内存中可能具有相同表示的事物,即使它们具有不同的含义并且应该在不同的地方使用。
- 1 回答
- 0 关注
- 169 浏览
添加回答
举报
0/150
提交
取消