В Go есть механизм встраивания структур (struct embedding), который позволяет составлять типы. Примерно это выглядит так:
type Position struct {
X int
Y int
}
type Colour struct {
R byte
G byte
B byte
}
type Rectangle struct {
Position
Colour
Width int
Height int
}
r := Rectangle{/* ... */}
// This works:
fmt.Printf("%d,%d\n", r.Position.X, r.Position.Y)
// but so does this:
fmt.Printf("%d,%d\n", r.X, r.Y)
А как вы думаете, что делает этот код?
type FooService struct {
URL string
}
type BarConnectionOptions struct {
URL string
}
type BarService struct {
BarConnectionOptions
}
type Options struct {
FooService
BarService
}
opts := Options{
FooService: FooService{URL: "abc.com"},
BarService: BarService{
BarConnectionOptions: BarConnectionOptions{
URL: "xyz.com",
},
},
}
fmt.Println(opts.URL)
Я бы ожидал, что компиляция упадет из-за неоднозначности поля URL. На самом деле программа выводит
abc.com, по всей видимости, выбирая наименее вложенную версию этого поля. Такое у нас случилось на работе, к счастью, это поймали тесты. Будьте внимательны при встраивании структур!