Em Go, uma struct é uma sequência de elementos nomeados chamados campos, e cada campo tem um nome e um tipo.
O nome de um campo deve ser único dentro da struct.
Structs podem ser comparadas com classes no paradigma da Programação Orientada a Objetos.
Você cria uma nova struct usando as palavras-chave type e struct, e define explicitamente o nome e o tipo dos campos.
Por exemplo, aqui definimos a struct Shape, que guarda o nome de uma forma e o seu tamanho:
type Shape struct {
name string
size int
}
Os nomes dos campos em structs seguem a convenção do Go: campos cujo nome começa com letra minúscula são visíveis apenas para o código do mesmo pacote, enquanto os que começam com letra maiúscula são visíveis em outros pacotes.
Depois de definir a struct, você precisa criar uma nova instância definindo os campos pelo nome do campo,
em qualquer ordem:
s := Shape {
name: "Square",
size: 25,
}
Para ler ou modificar os campos de uma instância, use 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
Campos que não têm um valor inicial atribuído terão 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
Você pode criar uma instância de uma struct sem usar os nomes dos campos, desde que defina os campos na ordem:
s := Shape {
"Oval",
20,
}
No entanto, essa sintaxe é considerada código frágil, pois pode quebrar quando um campo é adicionado, especialmente quando o novo campo é de um tipo diferente.
No exemplo a seguir, adicionamos um campo extra a 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{...}
Às vezes é bom ter funções que nos ajudem a criar instâncias de struct.
Por convenção, essas funções costumam se chamar New ou ter nomes que começam com New, mas, como são apenas funções comuns, você pode dar a elas o nome que quiser.
Elas podem lembrar os construtores de outras linguagens, mas em Go são apenas funções comuns.
No exemplo a seguir, uma dessas funções New é usada para criar uma nova instância de Shape e definir automaticamente um valor padrão 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 costumam ser declaradas no mesmo pacote das structs que inicializam, elas podem inicializar até campos privados da structNeste exercício, você vai organizar corridas entre vários tipos de carros de controle remoto. Cada carro tem sua própria velocidade e suas próprias características de consumo de bateria.
Os carros começam com a bateria cheia (100%). Cada vez que você dirige o carro com o controle remoto, ele percorre em metros a velocidade do carro e reduz a porcentagem restante de bateria de acordo com o consumo dela.
Se a bateria de um carro estiver abaixo da porcentagem de consumo da bateria, você não pode mais dirigi-lo.
Cada pista de corrida tem sua própria distância. Os carros são testados verificando se conseguem terminar a pista sem ficar sem bateria.
Defina uma struct Car com os seguintes campos do tipo int:
Permita criar um carro de controle remoto definindo uma função NewCar que recebe a velocidade do carro em metros
e a porcentagem de consumo da bateria como seus dois parâmetros (ambos do tipo int) e retorna uma instância de Car:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
// => Car{speed: 5, batteryDrain: 2, battery:100, distance: 0}
Defina outro tipo struct chamado Track com o campo distance do tipo inteiro.
Permita criar uma pista de corrida definindo uma função NewTrack que recebe a distância da pista em metros como seu único parâmetro (que é do tipo int):
distance := 800
track := NewTrack(distance)
// => Track{distance: 800}
Implemente a função Drive que atualiza o número de metros percorridos com base na velocidade do carro e reduz a bateria de acordo com o consumo dela.
Se não houver bateria suficiente para dirigir mais uma vez, o carro não se move:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
car = Drive(car)
// => Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}
Para terminar uma corrida, um carro precisa ser capaz de percorrer a distância da corrida.
Isso significa não esgotar a bateria antes de cruzar a linha de chegada.
Implemente a função CanFinish que recebe uma instância de Car e uma instância de Track como seus parâmetros e retorna true se o carro conseguir terminar a corrida; caso contrário, retorne false.
Considere que você está na linha de partida da corrida e liga o motor do carro para a corrida. Leve em conta que a bateria do carro pode não estar necessariamente cheia ao começar a corrida:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
distance := 100
track := NewTrack(distance)
CanFinish(car, track)
// => true
Crie sua conta no Exercism para aprender e dominar Go com 34 conceitos165 exercícios e mentoria humana de verdade, tudo de graça.