Percursos
/
Go
Go
/
Exercícios
/
Os brinquedos do Jedlik
Os brinquedos do Jedlik

Os brinquedos do Jedlik

Exercício de aprendizagem

Introdução

Um método é uma função com um argumento especial, o recetor. O recetor aparece na sua própria lista de argumentos, entre a palavra-chave func e o nome do método.

func (receiver type) MethodName(parameters) (returnTypes) {
}

Só podes definir um método com um recetor cujo tipo esteja definido no mesmo pacote que o método.

package person 

type Person struct {
	Name string
}

func (p Person) Greetings() string {
	return fmt.Sprintf("Welcome %s!", p.Name)
}

O método do tipo struct pode ser chamado com a notação de ponto.

p := Person{Name: "Bronson"}
fmt.Println(p.Greetings())
// Output: Welcome Bronson!

Repara como chamámos o método Greetings() à instância p de Person. É exatamente como chamas métodos numa linguagem de programação orientada a objetos.

Lembra-te: um método é apenas uma função com um argumento recetor. Os métodos ajudam a evitar conflitos de nomes, pois, como um método está associado a um tipo de recetor específico, podes ter o mesmo nome de método em tipos diferentes.

import "math"

type rect struct {
	width, height int
}
func (r rect) area() int {
	return r.width * r.height
}

type circle struct {
	radius int
}
func (c circle) area() float64 {
	return math.Pow(float64(c.radius), 2) * math.Pi
}

Há dois tipos de recetores: os recetores de valor e os recetores de ponteiro.

Todos os métodos que vimos até agora têm um recetor de valor, o que significa que recebem uma cópia do valor passado ao método. Por outras palavras, qualquer modificação feita ao recetor dentro do método não é visível para quem o chama.

Podes declarar métodos com recetores de ponteiro para modificar o valor para o qual o recetor aponta. Para isso, coloca um * antes do nome do tipo. Por exemplo, com o tipo rect, um recetor de ponteiro seria declarado como *rect. Essas modificações também são visíveis para quem chama o método.

type rect struct {
	width, height int
}
func (r *rect) squareIt() {
	r.height = r.width
}

r := rect{width: 10, height: 20}
fmt.Printf("Width: %d, Height: %d\n", r.width, r.height)
// Output: Width: 10, Height: 20

r.squareIt()
fmt.Printf("Width: %d, Height: %d\n", r.width, r.height)
// Output: Width: 10, Height: 10

Instruções

Nota: Este exercício é uma continuação do exercício need-for-speed.

Neste exercício vais organizar corridas entre vários tipos de carros telecomandados. Cada carro tem as suas próprias características de velocidade e de consumo de bateria.

Os carros começam com a bateria cheia (100%). Cada vez que conduzes o carro com o telecomando, ele percorre em metros uma distância igual à velocidade do carro e a percentagem de bateria restante diminui no valor do seu consumo de bateria.

Se a bateria de um carro estiver abaixo da percentagem do seu consumo de bateria, já não podes conduzir o carro.

O carro telecomandado tem um ecrã LED sofisticado que mostra duas informações:

  • A distância total percorrida, apresentada como: "Driven <METERS> meters".
  • A carga restante da bateria, apresentada como: "Battery at <PERCENTAGE>%".

Cada pista tem a sua própria distância. Os carros são testados verificando se conseguem terminar a pista sem ficar sem bateria.

1. Conduz o carro

Implementa o método Drive no Car, que atualiza o número de metros percorridos com base na velocidade do carro e reduz a bateria de acordo com o consumo de bateria:

speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
car.Drive()
// car is now Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}

Nota: Não deves tentar conduzir o carro se isso fizer com que a bateria do carro fique abaixo de 0.

2. Mostra a distância percorrida

Implementa um método DisplayDistance no Car para devolver a distância tal como é apresentada no ecrã LED, como string:

speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)

fmt.Println(car.DisplayDistance())
// Output: "Driven 0 meters"

3. Mostra a percentagem da bateria

Implementa o método DisplayBattery no Car para devolver a percentagem da bateria tal como é apresentada no ecrã LED, como string:

speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)

fmt.Println(car.DisplayBattery())
// Output: "Battery at 100%"

4. Verifica se um carro telecomandado consegue terminar uma corrida

Para terminar uma corrida, um carro tem de conseguir percorrer a distância da corrida. Isto significa não ficar sem bateria antes de cruzar a linha de chegada. Implementa o método CanFinish, que recebe um trackDistance int como parâmetro e devolve true se o carro conseguir terminar a corrida; caso contrário, devolve false:

speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)

trackDistance := 100

car.CanFinish(trackDistance)
// => true
Editar via GitHub A ligação abre numa nova janela ou separador
Go Exercism

Estás pronto para começar Os brinquedos do Jedlik?

Inscreve-te no Exercism para aprenderes e dominares Go com 34 conceitos166 exercícios, e mentoria humana real, tudo grátis.