package main import "fmt" // A struct is a collection of fields. It's useful for grouping data together to form records. type person struct { name string age int } // A struct literal is a list of field values enclosed in braces. You can specify field names or just provide values in order. // Instead of constructors, Go often uses factory functions that return a pointer to a struct. // This allows for more flexible initialization and can encapsulate any setup logic. func newPerson(name string) *person { p := person{name: name} p.age = 42 return &p } func main() { // Here we create a new person struct using a struct literal. We specify the field values in order without field names. fmt.Println(person{"Bob", 20}) // We can also specify field names in the struct literal. This way, the order of fields does not matter. fmt.Println(person{name: "Alice", age: 30}) // Omitted fields will be set to their zero value. For example, the age field will be set to 0. fmt.Println(person{name: "Fred"}) // You can also create a struct using the & operator to get a pointer to the struct. This is often more efficient when passing structs around. fmt.Println(&person{name: "Ann", age: 40}) // Using a factory function to create a new person struct. This allows us to encapsulate any initialization logic and return a pointer to the struct. fmt.Println(newPerson("Jon")) s := person{name: "Sean", age: 50} // Struct fields are accessed using a dot. fmt.Println(s.name) // You can also access fields through a struct pointer. // The language automatically dereferences the pointer to access the field. sp := &s fmt.Println(sp.age) // Struct fields can be modified through a struct pointer as well. The following statement // also changes the value of s.age because sp and s point to the same struct in memory. sp.age = 51 fmt.Println(sp.age) // Anonymous struct is a struct without a name. It's useful for grouping data together without having to define a new type. dog := struct { name string isGood bool }{ "Rex", true, } fmt.Println(dog) }