【发布时间】:2015-02-22 04:32:20
【问题描述】:
在以下代码中,sn -p 最后三个赋值产生编译错误:
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
)
}
这意味着,在这个例子中,只有布尔值、字符串和浮点数是不可赋值的。 其原因可以在规范中找到:
值 x 可分配给 T 类型的变量(“x 可分配给 T") 在任何这些情况下:
- [...]
- x 的类型 V 和 T 具有相同的基础类型,并且 V 或 T 中的至少一个不是命名类型。
- [...]
(Go Specification: Assignability)
和
[...] 命名类型由(可能是限定的)类型名称指定;未命名类型使用类型文字指定,该类型文字由现有类型组成新类型。 [...]
结合这一点,别名assign不起作用的原因是因为命名了最后三种情况的类型。这样就违反了规则:两个命名类型是赋值的一部分。
现在是我的实际问题:
为什么不允许将别名字符串/布尔值/数字分配给实际的字符串/布尔值/数字,而不是像切片和数组这样的类型?
缺少这条规则会导致什么样的问题?
将字符串指定为命名类型会导致哪些类型的问题?
提前谢谢你。
【问题讨论】:
-
你当然可以问“为什么我不能有不同的语言?” Stack Overflow 上的问题,答案可能是“看起来你可以,现在你只需要实际构建它。”不过,比起学术问题,我更喜欢回答帮助人们构建事物的问题。
-
@twotwotwo 嗯,我问这个问题的主要原因是因为我知道 Go 的设计者花了很多心思在它上面,所以在这样的决定背后大概有某种想法,我别看。很抱歉,这个问题不是为了解决特定问题,而是更多关于语言设计的问题(总的来说,因为我认为 Go 不是唯一强制执行此规则的语言)。我在这里问是希望比我更了解语言设计的人能够详细说明为什么事情通常会以这种方式完成。
-
我认为有一种方法可以解决这个编程问题(“我如何使用两个命名类型的不可分配性?),我正在试一试。