Reputation: 7787
What is the difference between these two structs other than that they aren't considered equivalent?
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
}
They look the same:
$ go run a.go
{1} {1}
{2} {2}
But if you uncomment a = b
, it says:
$ go run a.go
# command-line-arguments
./a.go:10: cannot use b (type struct { int int }) as type struct { int } in assignment
Yet struct{a,b int}
and struct{a int;b int}
are equivalent:
package main
func main() {
a := struct{a,b int}{1,2}
b := struct{a int;b int}{1,2}
a = b
b = a
}
?
Upvotes: 5
Views: 498
Reputation: 166825
struct { int }
is a struct with an anonymous field of type int
.
struct { int int }
is a struct with a field named int
of type int
.
int
is not a keyword; it can be used as an identifier.
The struct types are not identical; the corresponding fields do not have the same names.
A field declared with a type but no explicit field name is an anonymous field and the unqualified type name acts as the anonymous field name. Therefore, field names a.int
and b.int
are valid. For example,
a := struct{ int }{1}
b := struct{ int int }{1}
a.int = 2
b.int = a.int
The Go Programming Language Specification
A struct is a sequence of named elements, called fields, each of which has a name and a type. Field names may be specified explicitly (IdentifierList) or implicitly (AnonymousField). Within a struct, non-blank field names must be unique.
StructType = "struct" "{" { FieldDecl ";" } "}" . FieldDecl = (IdentifierList Type | AnonymousField) [ Tag ] . AnonymousField = [ "*" ] TypeName .
A field declared with a type but no explicit field name is an anonymous field, also called an embedded field or an embedding of the type in the struct. An embedded type must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.
The following keywords are reserved and may not be used as identifiers.
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
Two struct types are identical if they have the same sequence of fields, and if corresponding fields have the same names, and identical types, and identical tags. Two anonymous fields are considered to have the same name. Lower-case field names from different packages are always different.
Upvotes: 9