Skip to content

Go-Methoden

Eine Methode ist eine Funktion mit einem Empfänger. Der Empfänger kann ein benutzerdefinierter Typ oder ein Basis-Typ sein.

Deklaration

Das Format der Methodendeklaration lautet wie folgt:

go
func (Empfänger) Methodenname(Parameter) Rückgabewert {
   Methodenrumpf
}

Beispiel:

go
type Person struct {
   Name string
   Age  int
}

func (p Person) SayHello() {
   fmt.Printf("Hallo, mein Name ist %s\n", p.Name)
}

In diesem Beispiel ist Person der Empfängertyp und p der Empfänger. SayHello ist die Methodenname.

Wertempfänger vs. Zeigerempfänger

Es gibt zwei Arten von Empfängern: Wertempfänger und Zeigerempfänger.

Wertempfänger

Ein Wertempfänger erhält eine Kopie des Werts. Änderungen am Empfänger wirken sich nicht auf den ursprünglichen Wert aus.

go
type Person struct {
   Name string
   Age  int
}

func (p Person) SetName(name string) {
   p.Name = name
}

func main() {
   p := Person{Name: "Alice", Age: 25}
   p.SetName("Bob")
   fmt.Println(p.Name) // Alice
}

Zeigerempfänger

Ein Zeigerempfänger erhält einen Zeiger auf den Wert. Änderungen am Empfänger wirken sich auf den ursprünglichen Wert aus.

go
type Person struct {
   Name string
   Age  int
}

func (p *Person) SetName(name string) {
   p.Name = name
}

func main() {
   p := Person{Name: "Alice", Age: 25}
   p.SetName("Bob")
   fmt.Println(p.Name) // Bob
}

TIP

Wenn der Empfänger ein großer Strukturtyp ist, ist es effizienter, einen Zeigerempfänger zu verwenden, da keine Kopie erstellt werden muss.

Methodenaufruf

Methoden können auf Werte und Zeiger aufgerufen werden. Go konvertiert automatisch zwischen ihnen.

go
type Person struct {
   Name string
   Age  int
}

func (p Person) SayHello() {
   fmt.Printf("Hallo, mein Name ist %s\n", p.Name)
}

func (p *Person) SetAge(age int) {
   p.Age = age
}

func main() {
   p := Person{Name: "Alice", Age: 25}
   p.SayHello()      // &p wird automatisch verwendet
   p.SetAge(26)      // p wird automatisch verwendet
   (&p).SayHello()   // p wird automatisch verwendet
   (&p).SetAge(27)   // &p wird automatisch verwendet
}

Methoden mit gleichem Namen

Methoden mit gleichem Namen können in verschiedenen Typen definiert werden.

go
type Dog struct{}
type Cat struct{}

func (d Dog) Speak() {
   fmt.Println("Woof!")
}

func (c Cat) Speak() {
   fmt.Println("Meow!")
}

Methodenexport

Methoden können exportiert werden, indem der Methodenname mit einem Großbuchstaben beginnt.

go
type Person struct {
   name string
}

func (p *Person) SetName(name string) {
   p.name = name
}

func (p *Person) GetName() string {
   return p.name
}

In diesem Beispiel sind SetName und GetName exportierte Methoden, die von anderen Paketen aufgerufen werden können.

Methoden für Basis-Typen

Methoden können auch für Basis-Typen definiert werden.

go
type MyInt int

func (m MyInt) IsEven() bool {
   return m%2 == 0
}

func main() {
   n := MyInt(4)
   fmt.Println(n.IsEven()) // true
}

TIP

Methoden können nicht für nicht-benutzerdefinierte Typen definiert werden. Zum Beispiel können Sie keine Methode für int definieren.

Embedding

Wenn eine Struktur eine andere Struktur embeddet, werden die Methoden der eingebetteten Struktur auch für die äußere Struktur verfügbar.

go
type Animal struct{}

func (a Animal) Eat() {
   fmt.Println("Essen")
}

type Dog struct {
   Animal
}

func main() {
   d := Dog{}
   d.Eat() // Dog kann Animal.Eat aufrufen
}

Methoden vs. Funktionen

Der Hauptunterschied zwischen Methoden und Funktionen ist, dass Methoden einen Empfänger haben. Methoden können auf Werte oder Zeiger aufgerufen werden, während Funktionen direkt aufgerufen werden.

go
// Funktion
func Add(a, b int) int {
   return a + b
}

// Methode
type MyInt int

func (m MyInt) Add(n MyInt) MyInt {
   return m + n
}

Golang by www.golangdev.cn edit