Μια μέθοδος είναι μια συνάρτηση με ένα ειδικό όρισμα δέκτη.
Ο δέκτης εμφανίζεται στη δική του λίστα ορισμάτων, ανάμεσα στη λέξη-κλειδί func και το όνομα της μεθόδου.
func (receiver type) MethodName(parameters) (returnTypes) {
}
Μπορείς να ορίσεις μια μέθοδο με δέκτη μόνο αν ο τύπος του είναι ορισμένος στο ίδιο πακέτο με τη μέθοδο.
package person
type Person struct {
Name string
}
func (p Person) Greetings() string {
return fmt.Sprintf("Welcome %s!", p.Name)
}
Τη μέθοδο στη δομή μπορείς να την καλέσεις χρησιμοποιώντας τη σημειογραφία της τελείας.
p := Person{Name: "Bronson"}
fmt.Println(p.Greetings())
// Output: Welcome Bronson!
Πρόσεξε τον τρόπο με τον οποίο καλέσαμε τη μέθοδο Greetings() στο στιγμιότυπο Person p.
Είναι ακριβώς όπως καλείς μεθόδους σε μια αντικειμενοστρεφή γλώσσα προγραμματισμού.
Θυμήσου: μια μέθοδος δεν είναι παρά μια συνάρτηση με όρισμα δέκτη. Οι μέθοδοι βοηθούν να αποφεύγεις συγκρούσεις ονομάτων, καθώς μια μέθοδος είναι δεμένη με έναν συγκεκριμένο τύπο δέκτη, οπότε μπορείς να έχεις το ίδιο όνομα μεθόδου σε διαφορετικούς τύπους.
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
}
Υπάρχουν δύο είδη δεκτών: οι δέκτες τιμής και οι δέκτες δείκτη.
Όλες οι μέθοδοι που έχουμε δει μέχρι τώρα έχουν δέκτη τιμής, που σημαίνει ότι λαμβάνουν ένα αντίγραφο της τιμής που περνιέται στη μέθοδο. Αυτό σημαίνει ότι οποιαδήποτε τροποποίηση γίνει στον δέκτη μέσα στη μέθοδο δεν είναι ορατή σε αυτόν που καλεί τη μέθοδο.
Μπορείς να δηλώσεις μεθόδους με δέκτες δείκτη, ώστε να τροποποιήσεις την τιμή στην οποία δείχνει ο δέκτης.
Αυτό γίνεται βάζοντας ένα * μπροστά από το όνομα του τύπου.
Για παράδειγμα, με τον τύπο rect, ένας δέκτης δείκτη δηλώνεται ως *rect.
Τέτοιες τροποποιήσεις είναι ορατές και σε αυτόν που καλεί τη μέθοδο.
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
Σημείωση: Αυτή η άσκηση είναι συνέχεια της άσκησης need-for-speed.
Σε αυτή την άσκηση θα οργανώσεις αγώνες ανάμεσα σε διάφορους τύπους τηλεκατευθυνόμενων αυτοκινήτων. Κάθε αυτοκίνητο έχει τα δικά του χαρακτηριστικά ταχύτητας και κατανάλωσης μπαταρίας.
Τα αυτοκίνητα ξεκινούν με πλήρεις μπαταρίες (100%). Κάθε φορά που οδηγείς το αυτοκίνητο με το τηλεχειριστήριο, διανύει απόσταση σε μέτρα ίση με την ταχύτητα του αυτοκινήτου και μειώνει το υπόλοιπο ποσοστό μπαταρίας κατά την κατανάλωση μπαταρίας του.
Αν η μπαταρία ενός αυτοκινήτου είναι κάτω από το ποσοστό κατανάλωσης μπαταρίας του, δεν μπορείς πλέον να οδηγήσεις το αυτοκίνητο.
Το τηλεκατευθυνόμενο αυτοκίνητο έχει μια εντυπωσιακή οθόνη LED που εμφανίζει δύο πληροφορίες:
"Driven <METERS> meters"."Battery at <PERCENTAGE>%".Κάθε πίστα αγώνα έχει τη δική της απόσταση. Δοκιμάζουμε τα αυτοκίνητα ελέγχοντας αν μπορούν να τερματίσουν την πίστα χωρίς να ξεμείνουν από μπαταρία.
Υλοποίησε τη μέθοδο Drive στο Car που ενημερώνει τον αριθμό των μέτρων που έχουν διανυθεί με βάση την ταχύτητα του αυτοκινήτου και μειώνει την μπαταρία σύμφωνα με την κατανάλωση μπαταρίας:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
car.Drive()
// car is now Car{speed: 5, batteryDrain: 2, battery: 98, distance: 5}
Σημείωση: Δεν πρέπει να προσπαθήσεις να οδηγήσεις το αυτοκίνητο αν αυτό θα έχει ως αποτέλεσμα η μπαταρία του αυτοκινήτου να πέσει κάτω από 0.
Υλοποίησε μια μέθοδο DisplayDistance στο Car που επιστρέφει την απόσταση όπως εμφανίζεται στην οθόνη LED ως string:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayDistance())
// Output: "Driven 0 meters"
Υλοποίησε τη μέθοδο DisplayBattery στο Car που επιστρέφει το ποσοστό μπαταρίας όπως εμφανίζεται στην οθόνη LED ως string:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
fmt.Println(car.DisplayBattery())
// Output: "Battery at 100%"
Για να τερματίσει έναν αγώνα, το αυτοκίνητο πρέπει να μπορεί να διανύσει την απόσταση του αγώνα.
Αυτό σημαίνει να μην έχει καταναλώσει την μπαταρία του πριν περάσει τη γραμμή τερματισμού.
Υλοποίησε τη μέθοδο CanFinish που δέχεται ως παράμετρο ένα trackDistance int και επιστρέφει true αν το αυτοκίνητο μπορεί να τερματίσει τον αγώνα, αλλιώς επιστρέφει false:
speed := 5
batteryDrain := 2
car := NewCar(speed, batteryDrain)
trackDistance := 100
car.CanFinish(trackDistance)
// => true
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Go με 34 έννοιες166 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.