Em Go, um struct é uma sequência de elementos com nome chamados campos; cada campo tem um nome e um tipo.
O nome de um campo tem de ser único dentro da struct.
As structs podem ser comparadas às classes do paradigma da Programação Orientada a Objetos.
Crias uma nova struct com as palavras-chave type e struct e defines explicitamente o nome e o tipo dos campos.
Por exemplo, aqui definimos a struct Shape, que guarda o nome de uma forma geométrica e o seu tamanho:
type Shape struct {
name string
size int
}
Os nomes dos campos nas structs seguem a convenção de Go: os campos cujo nome começa por letra minúscula só são visíveis para o código do mesmo pacote, enquanto os que começam por letra maiúscula são visíveis noutros pacotes.
Depois de definires a struct, precisas de criar uma nova instância, indicando os campos pelo nome, em qualquer ordem:
s := Shape {
name: "Square",
size: 25,
}
Para ler ou modificar os campos de uma instância, usa a notação .:
// Update the name and the size
s.name = "Circle"
s.size = 35
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: Circle size: 35
Os campos aos quais não é atribuído um valor inicial ficam com o seu valor zero. Por exemplo:
s := Shape{name: "Circle"}
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: Circle size: 0
Podes criar uma instância de uma struct sem usar os nomes dos campos, desde que os definas por ordem:
s := Shape {
"Oval",
20,
}
No entanto, esta sintaxe é considerada código frágil, porque pode quebrar-se quando se adiciona um campo, sobretudo se o novo campo for de um tipo diferente.
No exemplo seguinte, adicionamos um campo extra à Shape:
type Shape struct {
name string
description string // new field 'description' added
size int
}
s := Shape{
"Circle",
20,
}
// Since the second field of the struct is now a string and not an int,
// the compiler will throw an error when compiling the program:
// Output: cannot use 20 (type untyped int) as type string in field value
// Output: too few values in Shape{...}
Por vezes, é útil ter funções que nos ajudam a criar instâncias de structs.
Por convenção, estas funções chamam-se normalmente New ou têm nomes que começam por New, mas, como são apenas funções normais, podes dar-lhes o nome que quiseres.
Podem fazer-te lembrar os construtores de outras linguagens, mas em Go são apenas funções normais.
No exemplo seguinte, uma destas funções New é usada para criar uma nova instância de Shape e definir automaticamente um valor predefinido para o size da forma:
func NewShape(name string) Shape {
return Shape{
name: name,
size: 100, //default-value for size is 100
}
}
NewShape("Triangle")
// => Shape { name: "Triangle", size: 100 }
Usar funções New pode trazer as seguintes vantagens:
New são frequentemente declaradas no mesmo pacote das structs que inicializam, podem inicializar até os campos privados da structPara aprofundares este tipo, podes consultar estes recursos: Go by Example: Structs, A Tour of Go: Structs ou Structures in Go (structs)
new
Outra forma de criar uma nova instância de uma struct é usar a função incorporada new:
s := new(Shape) // s will be of type *Shape (pointer to shape)
fmt.Printf("name: %s size: %d\n", s.name, s.size)
// Output: name: size: 0
Neste exemplo, new cria uma instância da struct Shape com todos os valores inicializados ao valor zero do seu tipo e devolve um ponteiro para ela.
Na maioria dos casos, não vais ver novas instâncias de structs criadas com a função incorporada new.
Dá sempre preferência a um literal de struct, a uma função New personalizada ou a qualquer outra função fornecida pelo pacote que te ajude a construir uma struct.
Usa a função incorporada new para criar novas instâncias de structs em último recurso.