Une méthode est une fonction avec un argument récepteur particulier.
Le récepteur apparaît dans sa propre liste d'arguments, entre le mot-clé func et le nom de la méthode.
func (receiver type) MethodName(parameters) (returnTypes) {
}
Tu ne peux définir une méthode avec un récepteur que si le type de ce récepteur est défini dans le même paquet que la méthode.
package person
type Person struct {
Name string
}
func (p Person) Greetings() string {
return fmt.Sprintf("Welcome %s!", p.Name)
}
La méthode définie sur la structure peut être appelée avec la notation pointée.
p := Person{Name: "Bronson"}
fmt.Println(p.Greetings())
// Output: Welcome Bronson!
Remarque la façon dont on a appelé la méthode Greetings() sur l'instance p de Person.
C'est exactement comme on appelle les méthodes dans un langage de programmation orienté objet.
Rappel : une méthode n'est qu'une fonction avec un argument récepteur. Les méthodes aident à éviter les conflits de nommage. En effet, comme une méthode est liée à un type de récepteur particulier, on peut avoir le même nom de méthode sur des types différents.
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
}
Il existe deux types de récepteurs : les récepteurs de valeur et les récepteurs de pointeur.
Toutes les méthodes que l'on a vues jusqu'ici ont un récepteur de valeur, ce qui signifie qu'elles reçoivent une copie de la valeur passée à la méthode. Toute modification effectuée sur le récepteur à l'intérieur de la méthode n'est donc pas visible pour l'appelant.
Tu peux déclarer des méthodes avec des récepteurs de pointeur afin de modifier la valeur vers laquelle pointe le récepteur.
Pour cela, on fait précéder le nom du type d'un *.
Par exemple, pour le type rect, un récepteur de pointeur serait déclaré *rect.
Ces modifications sont également visibles pour l'appelant de la méthode.
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
Remarque : cet exercice est la suite de l'exercice need-for-speed.
Dans cet exercice, tu vas organiser des courses entre différents types de voitures télécommandées. Chaque voiture possède ses propres caractéristiques de vitesse et de décharge de batterie.
Au départ, les voitures ont une batterie pleine (100 %). Chaque fois que tu conduis la voiture avec la télécommande, elle parcourt un nombre de mètres égal à la vitesse de la voiture et réduit le pourcentage de batterie restant de sa décharge.
Si la batterie d'une voiture est en dessous de son pourcentage de décharge, on ne peut plus conduire la voiture.
La voiture télécommandée dispose d'un écran LED sophistiqué qui affiche deux informations :
"Driven <METERS> meters"."Battery at <PERCENTAGE>%".Chaque piste de course a sa propre distance. On teste les voitures en vérifiant si elles peuvent terminer la piste sans épuiser leur batterie.
Implémente la méthode Drive sur Car qui met à jour le nombre de mètres parcourus en fonction de la vitesse de la voiture, et réduit la batterie en fonction de sa décharge :
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
car.Drive()
// car is now Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}
Remarque : il ne faut pas essayer de conduire la voiture si cela doit faire passer sa batterie en dessous de 0.
Implémente une méthode DisplayDistance sur Car pour renvoyer la distance telle qu'affichée sur l'écran LED sous forme de string :
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayDistance())
// Output: "Driven 0 meters"
Implémente la méthode DisplayBattery sur Car pour renvoyer le pourcentage de batterie tel qu'affiché sur l'écran LED sous forme de string :
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayBattery())
// Output: "Battery at 100%"
Pour terminer une course, une voiture doit pouvoir parcourir la distance de la course.
Cela signifie qu'elle ne doit pas épuiser sa batterie avant d'avoir franchi la ligne d'arrivée.
Implémente la méthode CanFinish qui prend un trackDistance int en paramètre et renvoie true si la voiture peut terminer la course ; sinon, renvoie false :
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
trackDistance := 100
car.CanFinish(trackDistance)
// => true
Inscris-toi sur Exercism pour apprendre et maîtriser Go avec 34 concepts166 exercices, et un vrai mentorat humain, le tout gratuitement.