首页 > 解决方案 > Go:关于结构数组初始化的困惑

问题描述

我的困惑显示在以下代码片段中:

type Ex struct{
    A,B int
}

a := []Ex{Ex{1, 2}, Ex{3, 4}}     //it works, and I understand it
b := []*Ex{&Ex{1, 2}, &Ex{3, 4}}   //it works, and I understand it
c := []Ex{{1, 2}, {3, 4}}   //it works, and I don't understand it
d := []*Ex{{1, 2}, {3, 4}}   //it works, and I don't understand it
e := []*Ex{{1, 2}, &Ex{3, 4}}   //it works, and I don't understand it

最让我困惑的是,两者都c := []Ex{{1, 2}, {3, 4}}可以d := []*Ex{{1, 2}, {3, 4}}很好地工作。为什么可以{1, 2}用来初始化一个对象和一个指针?

我发现了同样的问题,有人回答:

如果是 *Ex 或 *Track 之类的指针,它也会自动正确初始化:

但我期待更深入的解释。有没有关于这个问题的官方文件?

我有很好的 C/C++ 基础,但是 Golang 新手。期待您的回答,我提前感谢您。

标签: gostructinitializationslicecomposite-literals

解决方案


规范:复合文字:

在数组、切片或映射类型的复合文字中T,本身是复合文字的元素或映射键可以省略相应的文字类型,如果它与 的元素或键类型相同T&T类似地,当元素或键类型为 时,作为复合文字地址的元素或键可以省略*T

这说明了情况cd也说明了e

c := []Ex{{1, 2}, {3, 4}}
d := []*Ex{{1, 2}, {3, 4}}
e := []*Ex{{1, 2}, &Ex{3, 4}}

所有这些都是切片复合文字,并且元素也使用复合文字提供。所以引用的部分适用。根据规范,您可以从元素T的复合文字中省略元素类型(&如果它是指针类型,还可以省略运算符),在这种情况下,它是从切片的元素类型(“外部”复合文字)。

如果c,{1, 2}被解释为复合文字Ex{1, 2}

的情况下d{1, 2}被解释为&Ex{1, 2},即取复合字面量的地址Ex{1, 2}

这同样适用于大小写e(因为切片的元素类型相同)。

这是语言规范允许的复合文字的简化。当从切片类型中知道元素类型时,重复所有元素的元素类型只是多余的,使代码更长且更难阅读。


推荐阅读