
Go 1.27’s new struct literal field behavior can make code using embedded structs a little cleaner
A common pattern when representing entities is to pull the fields every entity shares into a base struct and embed it:
type Entity struct {
ID uuid.UUID
CreatedAt time.Time
UpdatedAt time.Time
}
type User struct {
Entity
Name string
Email string
}
Since Entity is embedded, you can already access its fields directly:
func WelcomeUser(user User) {
// using user fields
fmt.Printf("Welcome, user #%s! You joined at %s.\n", user.ID, user.CreatedAt.Format(time.Kitchen))
}
But before Go 1.27, when creating a struct literal, promoted fields couldn’t be used directly as keys
You had to write:
// we need to set Entity nested, or assign its fields separately
user := User{
Entity: Entity{
ID: uuid.New(),
},
Name: "Gopher",
Email: "gopher@gogogo.com",
//...
}
With Go 1.27, you can write:
user := User{
ID: uuid.New(), // the ID field got promoted from Entity to our User, we can set at initialization!
Name: "Gopher",
Email: "gopher@gogogo.com",
//...
}
The interesting part is that ID isn’t actually declared directly inside User. It’s a promoted field from the embedded Entity
This is a small language change, but it makes embedded structs much nicer to initialize, especially in codebases that rely heavily on composition to model entities.
The data used here is only for example purposes, if you use an ORM like GORM, ID, CreatedAt and UpdatedAt would probably be set automatically once you embed gorm.Model
As a bonus, uuid is also new in Go 1.27: it’s now part of the standard library, so uuid.New() here needs no third-party import! :)