From Chapter 7 of GOPL (Section 7.6), I noticed this line:
var tracks = []*Track{
{"Go", "Delilah", "From the Roots Up", 2012, length("3m38s")},
{"Go", "Moby", "Moby", 1992, length("3m37s")},
{"Go Ahead", "Alicia Keys", "As I Am", 2007, length("4m36s")},
{"Ready 2 Go", "Martin Solveig", "Smash", 2011, length("4m24s")},
}
I was kind of confused by how it initialized the slice of Track
pointers. So later I tried the following example:
type Ex struct {
A, B int
}
a := []Ex{Ex{1, 2}, Ex{3, 4}}
b := []Ex{{1, 2}, {3, 4}}
c := []*Ex{&Ex{1, 2}, &Ex{3, 4}}
d := []*Ex{{1, 2}, {3, 4}}
e := []*Ex{{1, 2}, &Ex{3, 4}}
I found all of the 5 cases are okay with no errors. The {1, 2}
seems to be a structure called "anonymous struct", but it confuses me since it works fine even when I am trying to fill in *Ex
pointers instead of Ex
struct.
Furthermore, when I try the following code, it complains syntax error:
f := []*Ex{&{1, 2}, &{3, 4}} // Syntax Error!
Can somebody help explain what is actually going on in these cases?
Please give more detail on your structure definition of Ex.
But, if Ex is implemented as this:
type Ex struct {
t interface{}
o interface{}
}
you don't give a pointer of anonymous struct because, the definition it's not know.
Also you can't do:
variable := new({1, 2})
// or
variable := {1, 2}
When you do:
b := []Ex{{1, 2}, {3, 4}}
// you create slice of Ex with two Ex struct
// so b := []Ex{Ex{t:1,o:2}, Ex{t:3, o:4}}
contrariwise:
f := []*Ex{&{1, 2}, &{3, 4}}
// you create slice of unknow definition type
// f = []Ex{Ex{t: addressOfUnknowType, o: addressOfUnknowType}}
I hope help you
I think anonymous isn't quite the correct word here. The struct has a name, "Track" or "Ex". But you are initializing it with a shortcut:
f := []<type>{{...}, {...}}
is roughly the same as:
f := []<type>{<type>{...}, <type>{...}}
But it's a little smarter than blind string replacement. If <type>
is a pointer like *Ex
or *Track
, it also automatically initializes correctly:
f := []*<type>{{...}, {...}} // is the same as...
f := []*<type>{&<type>{...}, &<type>{...}}
It works the same for maps:
f := map[string]*<type>{"a": {...}, "b": {...}} // is the same as...
f := map[string]*<type>{"a": &<type>{...}, "b": &<type>{...}}
For further clarification, anonymous structs are ones that have no separate type definition. These are anonymous types, but not anonymous structs. An anonymous struct is a struct with no associated type definition. This syntax of initializing values without referring to the type is essential to making the manageable:
f := []struct{
A, B int
}{
{1, 2}, {3, 4}
}
// or with pointers...
f := []*struct{
A, B int
}{
{1, 2}, {3, 4}
}
Here the struct within the list has no type definition, so it is anonymous. And thanks to the initialization shorthand, that's fine - I don't need a name to initialize it.