在以下代码段中,最后三个分配产生编译错误:
package main
type (
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,字符串和浮点数不可分配。 原因可以在规范中找到:
值x可赋值给T类型的变量(“x可赋值给 T“)在任何这些情况下:
- [...]
- x的类型V和T具有相同的基础类型,并且V或T中的至少一个不是命名类型。
- [...]
(Go Specification: Assignability)
和
[...]命名类型由(可能是合格的)类型名称指定;使用类型文字指定未命名的类型,类型文字从现有类型组成新类型。 [...]
结合这个,别名分配不起作用的原因是因为最后三个案例的类型被命名。通过此规则违反了规则:两个命名类型是分配的一部分。
现在我的实际问题:
为什么不允许将别名字符串/ bool / numeric分配给实际的字符串/ bool / numeric,而不是像片和数组这样的类型?
这条规则缺乏会导致什么样的问题?
作为命名类型的字符串规范会导致什么类型的问题?
提前谢谢。
答案 0 :(得分:0)
可分配性规则意味着您有时必须在命名类型之间进行转换以明确说出"是的,我的意思是此string
用作Foo
,"即使他们共享相同的基础类型。这与os.FileMode
之类的内容相关:它是下面的数字,但类型检查会让您不小心将其传递给带有不相关foo uint32
的函数。 (可分配性规则也会影响函数调用:您可以传递可分配给参数类型的任何类型的参数。)
通常,这意味着如果您对基础类型有明确的,可能混淆的用法,则可以为它们指定不同的名称。例如:基础类型[][4]float32
可能合理地分配了RGBASlice
,HSVASlice
和XYZWSlice
类型名称。您无法将RGBASlice
传递给期望XYZWSlice
的函数。但是所有这些都可以透明地传递给那些不关心数字意义的事情,比如你有一些通用的矢量数学例程。
因此,广泛地说,通过强制您在命名类型之间进行转换,Go可以帮助您区分可能在内存中具有相同表示形式的内容,即使它们具有不同的含义并且应该在不同的位置使用。