Un método es una función con un argumento receptor especial.
El receptor aparece en su propia lista de argumentos entre la palabra clave func y el nombre del método.
func (receiver type) MethodName(parameters) (returnTypes) {
}
Solo puedes definir un método con un receptor cuyo tipo esté definido en el mismo paquete que el método.
package person
type Person struct {
Name string
}
func (p Person) Greetings() string {
return fmt.Sprintf("Welcome %s!", p.Name)
}
Se puede llamar al método de la estructura mediante la notación de punto.
p := Person{Name: "Bronson"}
fmt.Println(p.Greetings())
// Output: Welcome Bronson!
Fíjate en cómo llamamos al método Greetings() en la instancia Person p.
Es exactamente igual que la forma en que llamas a métodos en un lenguaje de programación orientado a objetos.
Recuerda: un método es simplemente una función con un argumento receptor. Los métodos ayudan a evitar conflictos de nombres; puesto que un método está vinculado a un tipo de receptor concreto, puedes tener el mismo nombre de método en 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
}
Hay dos tipos de receptores: receptores de valor y receptores de puntero.
Todos los métodos que hemos visto hasta ahora tienen un receptor de valor, lo que significa que reciben una copia del valor pasado al método, es decir, que cualquier modificación realizada al receptor dentro del método no es visible para el llamador.
Puedes declarar métodos con receptores de puntero para modificar el valor al que apunta el receptor.
Esto se hace anteponiendo un * al nombre del tipo.
Por ejemplo, con el tipo rect, un receptor de puntero se declararía como *rect.
Estas modificaciones también son visibles para el llamador del 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
Nota: este ejercicio es una continuación del ejercicio need-for-speed.
En este ejercicio vas a organizar carreras entre varios tipos de coches teledirigidos. Cada coche tiene sus propias características de velocidad y de consumo de batería.
Los coches empiezan con la batería llena (100 %). Cada vez que conduces el coche con el mando a distancia, avanza tantos metros como indique la velocidad del coche y reduce el porcentaje de batería restante según su consumo de batería.
Si la batería de un coche está por debajo de su porcentaje de consumo de batería, ya no puedes conducirlo.
El coche teledirigido tiene una pantalla LED muy vistosa que muestra dos datos:
"Driven <METERS> meters"."Battery at <PERCENTAGE>%".Cada pista de carreras tiene su propia distancia. Los coches se ponen a prueba comprobando si pueden terminar la pista sin quedarse sin batería.
Implementa el método Drive de Car, que actualiza el número de metros recorridos según la velocidad del coche y reduce la batería según su consumo:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
car.Drive()
// car is now Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}
Nota: no intentes conducir el coche si al hacerlo la batería va a quedar por debajo de 0.
Implementa un método DisplayDistance en Car que devuelva la distancia tal y como se muestra en la pantalla LED, como un string:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayDistance())
// Output: "Driven 0 meters"
Implementa el método DisplayBattery de Car que devuelva el porcentaje de batería tal y como se muestra en la pantalla LED, como un string:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayBattery())
// Output: "Battery at 100%"
Para terminar una carrera, un coche tiene que ser capaz de recorrer la distancia de la carrera.
Esto significa no agotar la batería antes de cruzar la línea de meta.
Implementa el método CanFinish, que recibe un trackDistance int como parámetro y devuelve true si el coche puede terminar la carrera; en caso contrario, devuelve false:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
trackDistance := 100
car.CanFinish(trackDistance)
// => true
Regístrate en Exercism para aprender y dominar Go con 34 conceptos166 ejercicios y mentoría humana real, todo gratis.