Eine Methode ist eine Funktion mit einem speziellen Receiver-Argument.
Der Receiver erscheint in seiner eigenen Argumentliste zwischen dem func-Schlüsselwort und dem Namen der Methode.
func (receiver type) MethodName(parameters) (returnTypes) {
}
du kannst eine Methode nur mit einem Receiver definieren, dessen Typ im selben Paket wie die Methode definiert ist.
package person
type Person struct {
Name string
}
func (p Person) Greetings() string {
return fmt.Sprintf("Welcome %s!", p.Name)
}
Die Methode auf dem Struct kann über die Punktnotation aufgerufen werden.
p := Person{Name: "Bronson"}
fmt.Println(p.Greetings())
// Output: Welcome Bronson!
Schau dir an, wie wir die Methode Greetings() auf der Person-Instanz p aufgerufen haben.
Es ist genau so, wie du Methoden in einer objektorientierten Programmiersprache aufrufst.
Denk daran: Eine Methode ist nur eine Funktion mit einem Receiver-Argument. Methoden helfen, Namenskonflikte zu vermeiden: Da eine Methode an einen bestimmten Receiver-Typ gebunden ist, kannst du denselben Methodennamen auf verschiedenen Typen haben.
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
}
Es gibt zwei Arten von Receivern: Wert-Receiver und Zeiger-Receiver.
Alle Methoden, die wir bisher gesehen haben, haben einen Wert-Receiver. Das heißt, sie erhalten eine Kopie des Werts, der an die Methode übergeben wird. Änderungen am Receiver innerhalb der Methode sind daher für den Aufrufer nicht sichtbar.
du kannst Methoden mit Zeiger-Receivern deklarieren, um den Wert zu ändern, auf den der Receiver zeigt. Dazu setzt du ein * vor den Typnamen. Für den Typ rect würde ein Zeiger-Receiver beispielsweise als *rect deklariert. Solche Änderungen sind auch für den Aufrufer der Methode sichtbar.
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
Hinweis: Diese Übung ist eine Fortsetzung der Übung need-for-speed.
In dieser Übung organisierst du Rennen zwischen verschiedenen Arten von ferngesteuerten Autos. Jedes Auto hat seine eigene Geschwindigkeit und seinen eigenen Batterieverbrauch.
Die Autos starten mit vollen (100 %) Batterien. Jedes Mal, wenn du das Auto mit der Fernbedienung fährst, legt es die Geschwindigkeit des Autos in Metern zurück und verringert den verbleibenden Batteriestand um seinen Batterieverbrauch.
Wenn der Batteriestand eines Autos niedriger ist als sein Batterieverbrauch, kannst du das Auto nicht mehr fahren.
Das ferngesteuerte Auto hat eine schicke LED-Anzeige, die zwei Informationen anzeigt:
"Driven <METERS> meters"."Battery at <PERCENTAGE>%".Jede Rennstrecke hat ihre eigene Distanz. Die Autos werden getestet, indem geprüft wird, ob sie die Strecke beenden können, ohne dass ihnen die Batterie ausgeht.
Implementiere die Methode Drive auf Car, die die Anzahl der gefahrenen Meter anhand der Geschwindigkeit des Autos aktualisiert und die Batterie entsprechend dem Batterieverbrauch reduziert:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
car.Drive()
// car is now Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}
Hinweis: Du solltest nicht versuchen, das Auto zu fahren, wenn dadurch der Batteriestand unter 0 fallen würde.
Implementiere eine Methode DisplayDistance auf Car, die die Distanz so als string zurückgibt, wie sie auf der LED-Anzeige angezeigt wird:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayDistance())
// Output: "Driven 0 meters"
Implementiere die Methode DisplayBattery auf Car, die den Batteriestand in Prozent so als string zurückgibt, wie er auf der LED-Anzeige angezeigt wird:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayBattery())
// Output: "Battery at 100%"
Um ein Rennen zu beenden, muss ein Auto die Distanz des Rennens fahren können.
Das bedeutet, dass seine Batterie nicht leer sein darf, bevor es die Ziellinie überquert hat.
Implementiere die Methode CanFinish, die einen trackDistance int als Parameter entgegennimmt und true zurückgibt, wenn das Auto das Rennen beenden kann; andernfalls gib false zurück:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
trackDistance := 100
car.CanFinish(trackDistance)
// => true
Melde dich bei Exercism an, um Go mit 34 Konzepte166 Übungen und echtem menschlichen Mentoring zu lernen und zu meistern, alles kostenlos.