Um método é uma função com um argumento especial, o receptor.
O receptor aparece em sua própria lista de argumentos, entre a palavra-chave func e o nome do método.
func (receiver type) MethodName(parameters) (returnTypes) {
}
Você só pode definir um método com um receptor 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 da struct pode ser chamado com notação de ponto.
p := Person{Name: "Bronson"}
fmt.Println(p.Greetings())
// Output: Welcome Bronson!
Repare como chamamos o método Greetings() na instância p de Person.
É exatamente como você chama métodos em uma linguagem de programação orientada a objetos.
Lembre-se: um método é só uma função com um argumento receptor. Os métodos ajudam a evitar conflitos de nomes. Como um método está ligado a um tipo de receptor específico, você pode 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
}
Existem dois tipos de receptores: receptores de valor e receptores de ponteiro.
Todos os métodos que vimos até agora têm um receptor de valor. Isso significa que eles recebem uma cópia do valor passado ao método. Assim, qualquer alteração feita ao receptor dentro do método não é visível para quem chamou.
Você pode declarar métodos com receptores de ponteiro para modificar o valor para o qual o receptor aponta.
Isso é feito colocando um * antes do nome do tipo.
Por exemplo, com o tipo rect, um receptor 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
Observação: este exercício é uma continuação do exercício need-for-speed.
Neste exercício, você vai organizar corridas entre vários tipos de carros de controle remoto. Cada carro tem suas próprias características de velocidade e 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 diminui a porcentagem restante da bateria pelo seu consumo de bateria.
Se a bateria de um carro estiver abaixo da porcentagem do seu consumo de bateria, você não pode mais dirigir o carro.
O carro de controle remoto tem um display de LED bacana que mostra duas informações:
"Driven <METERS> meters"."Battery at <PERCENTAGE>%".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.
Implemente o método Drive em 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}
Observação: você não deve tentar dirigir o carro se isso fizer a bateria dele ficar abaixo de 0.
Implemente um método DisplayDistance em Car que retorne a distância exibida no display de LED como uma string:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayDistance())
// Output: "Driven 0 meters"
Implemente o método DisplayBattery em Car que retorne a porcentagem da bateria exibida no display de LED como uma string:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayBattery())
// Output: "Battery at 100%"
Para terminar uma corrida, o carro precisa conseguir percorrer a distância da corrida.
Isso significa não descarregar a bateria antes de cruzar a linha de chegada.
Implemente o método CanFinish, que recebe um trackDistance int como parâmetro e retorna true se o carro conseguir terminar a corrida; caso contrário, retorne false:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
trackDistance := 100
car.CanFinish(trackDistance)
// => true
Crie sua conta no Exercism para aprender e dominar Go com 34 conceitos166 exercícios e mentoria humana de verdade, tudo de graça.