noob here :) i'm having trouble understanding
when i do this in one file:
scratch.go
package main
import "fmt"
type foo struct {
field1 string
field2 string
}
type bar struct {
foo
field3 string
field4 string
}
func main() {
fooBar := bar{
foo{
"apples",
"banana",
},
"spam",
"eggs",
}
fmt.Printf("%#v\n", fooBar)
}
it works but when i have 3 files like this
rootproject
├── magazine
│ ├── address.go
│ └── employee.go
└── main.go
magazine/address.go
package magazine
type Address struct {
Street string
City string
State string
PostalCode string
}
magazine/employee.go
package magazine
type Employee struct {
Name string
Salary float64
Address
}
and
main.go
package main
import (
"fmt"
"magazine"
)
func main() {
employee := magazine.Employee{
Name: "pogi",
Salary: 69420,
magazine.Address{
Street: "23 pukinginamo st.",
City: "bactol city",
State: "betlog",
PostalCode: "23432",
},
}
fmt.Printf("%#v\n", employee)
}
it's error :(
mixture of field:value and value elements in struct literal
i don't get it, what am i doing wrong? i thought if the struct was nested it is said to be embedded in the outer struct and i can access the the fields of the inner struct from the outer one. which is the case for my first example(the singular file), but when i do it within packages. it's different?
CodePudding user response:
i thought if the struct was nested it is said to be embedded in the outer struct and i can access the the fields of the inner struct from the outer one.
Yes, you can access an embedded field's members directly, however that does not apply when constructing the struct with a composite literal. If you look through the rules for struct literals you'll find this one:
If any element has a key, every element must have a key.
This rule applies regardless of whether a field is embedded or not.
To fix the error you can either remove the other keys:
func main() {
employee := magazine.Employee{
"pogi",
69420,
magazine.Address{
Street: "23 pukinginamo st.",
City: "bactol city",
State: "betlog",
PostalCode: "23432",
},
}
fmt.Printf("%#v\n", employee)
}
Or you can specify all the keys:
func main() {
employee := magazine.Employee{
Name: "pogi",
Salary: 69420,
Address: magazine.Address{
Street: "23 pukinginamo st.",
City: "bactol city",
State: "betlog",
PostalCode: "23432",
},
}
fmt.Printf("%#v\n", employee)
}
Note that for an embedded field you can use the type's unqualified name to refer to the embedded field.
https://go.dev/ref/spec#Struct_types:
A field declared with a type but no explicit field name is called an embedded field. An embedded field must be specified as a type name
T
or as a pointer to a non-interface type name*T
, andT
itself may not be a pointer type. The unqualified type name acts as the field name.