Trilhas
/
Go
Go
/
Exercícios
/
Need for Speed
Need for Speed

Need for Speed

Exercício de aprendizagem

Introdução

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.

Definindo uma struct

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.

Criando instâncias de uma struct

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{...}

Funções "New"

À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:

  • validação dos valores fornecidos
  • tratamento de valores padrão
  • como as funções New costumam ser declaradas no mesmo pacote das structs que inicializam, elas podem inicializar até campos privados da struct

Instruções

Neste 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.

1. Crie um carro de controle remoto

Defina uma struct Car com os seguintes campos do tipo int:

  • battery
  • batteryDrain
  • speed
  • distance

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}

2. Crie uma pista de corrida

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}

3. Dirija o carro

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}

4. Verifique se um carro de controle remoto consegue terminar uma corrida

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
Editar via GitHub O link abre em uma nova janela ou aba
Go Exercism

Tudo pronto para começar Need for Speed?

Crie sua conta no Exercism para aprender e dominar Go com 34 conceitos165 exercícios e mentoria humana de verdade, tudo de graça.