这两种结构之间有什么区别,除了它们不被认为是等价的?
package main
import "fmt"
func main() {
a := struct{int}{1}
b := struct{int int}{1}
fmt.Println(a,b)
a.int=2
b.int=a.int
fmt.Println(a,b)
//a = b
}
Run Code Online (Sandbox Code Playgroud)
他们看起来一样:
$ go run a.go
{1} {1}
{2} {2}
Run Code Online (Sandbox Code Playgroud)
但如果你取消注释a = b,它会说:
$ go run a.go
# command-line-arguments
./a.go:10: cannot use b (type struct { int int }) as type struct { int } in assignment
Run Code Online (Sandbox Code Playgroud)
然而struct{a,b int}并且struct{a int;b int}是等价的:
package main
func main() {
a := struct{a,b int}{1,2}
b := struct{a int;b int}{1,2}
a = b
b = a
}
Run Code Online (Sandbox Code Playgroud)
?
struct { int }是一个具有匿名字段类型的结构int.
struct { int int }是一个带有名为inttype 的字段的结构int.
int不是关键字; 它可以用作标识符.
结构类型不相同; 相应的字段没有相同的名称.
使用类型但没有显式字段名称声明的字段是匿名字段,非限定类型名称充当匿名字段名称.因此,字段名a.int和b.int有效.例如,
a := struct{ int }{1}
b := struct{ int int }{1}
a.int = 2
b.int = a.int
Run Code Online (Sandbox Code Playgroud)
结构是一系列命名元素,称为字段,每个元素都有一个名称和一个类型.字段名称可以显式指定(IdentifierList)或隐式指定(AnonymousField).在结构中,非空字段名称必须是唯一的.
Run Code Online (Sandbox Code Playgroud)StructType = "struct" "{" { FieldDecl ";" } "}" . FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] . AnonymousField = [ "*" ] TypeName .使用类型但没有显式字段名称声明的字段是匿名字段,也称为嵌入字段或在结构中嵌入类型.必须将嵌入类型指定为类型名称T或指向非接口类型名称*T的指针,并且T本身可能不是指针类型.非限定类型名称充当字段名称.
以下关键字是保留的,不能用作标识符.
Run Code Online (Sandbox Code Playgroud)break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var如果两个结构类型具有相同的字段序列,并且相应的字段具有相同的名称,相同的类型和相同的标记,则它们是相同的.两个匿名字段被认为具有相同的名称.来自不同包的小写字段名称总是不同的.