猿问

Go 中的别名类型只能在未命名时分配吗?

在以下代码片段中,最后三个赋值产生了编译错误:


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、strings 和 floats 是不可分配的。原因可以在规范中找到:

在以下任一情况下,值 x 可分配给 T 类型的变量(“x 可分配给 T”):

  • [...]

  • x 的类型 V 和 T 具有相同的基础类型,并且 V 或 T 中至少有一个不是命名类型。

  • [...]

Go 规范:可分配性

[...] 命名类型由(可能限定的)类型名称指定;未命名类型使用类型文字指定,该类型文字从现有类型组成新类型。[...]

Go 规格: 类型)

结合这一点,别名assign不起作用的原因是因为命名了后三种情况的类型。这样就违反了规则:两个命名类型是赋值的一部分。

现在我的实际问题:

为什么不允许将别名字符串/bool/numeric 分配给实际的 string/bool/numeric,而不是像切片和数组这样的类型?

缺少这条规则会导致什么样的问题?

将字符串指定为命名类型会导致哪些问题?


holdtom
浏览 170回答 1
1回答

料青山看我应如是

可赋值性规则意味着您有时必须在命名类型之间进行转换以明确表示“是的,我的意思是string将其用作 a Foo”,即使它们共享相同的基础类型。这与以下内容相关os.FileMode:它是下面的数字,但类型检查将防止您意外将其传递给采用无关foo uint32. (可分配性规则也影响函数调用:您可以传递可分配给参数类型的任何类型的参数。)通常,这意味着如果您对底层类型有不同的、可能容易混淆的用途,您可以为它们分配不同的名称。像:底层类型[][4]float32可以正当的拥有RGBASlice,HSVASlice以及XYZWSlice类型名称分配。您不能将 a 传递RGBASlice给需要XYZWSlice. 但是,所有这些都可以透明地传递给不关心数字含义的事物,例如,如果您有一些通用的矢量数学例程。因此,从广义上讲,通过强制您在命名类型之间进行转换,Go 可以帮助您区分在内存中可能具有相同表示的事物,即使它们具有不同的含义并且应该在不同的地方使用。
随时随地看视频慕课网APP

相关分类

Go
我要回答