Achtergrond:
Go heeft een eenvoudige maar krachtige conceptie van methoden en interfaces geïmplementeerd, gebaseerd op duck typing. Methoden kunnen alleen aan benoemde types (struct of alias) worden toegevoegd, en interfaces vormen een verzameling van methoden. Dit is de sleutel tot polymorfisme en abstracties zonder noodzaak voor expliciete implements.
Probleem:
Programmeurs die uit Java of C# komen, verwachten vaak expliciete sleutelwoorden zoals implements of extends en raken in de war door de verschillen tussen methoden met een receiver op waarde en op pointer, wat leidt tot onvoorspelbaar gedrag en fouten bij de implementatie van interfaces.
Oplossing:
Definitie van methoden en interfaces:
type User struct { Name string } func (u User) Greet() string { return "Hallo, " + u.Name } func (u *User) SetName(name string) { u.Name = name } type Greeter interface { Greet() string }
Belangrijke kenmerken:
Kan je methoden declareren voor een type-alias met een basis type int of string?
Ja, als het een benoemd type is, bijvoorbeeld:
type MyInt int func (m MyInt) Double() int { return int(m) * 2 }
Wat is het verschil tussen het implementeren van een interface via methoden met een pointer en een waarde?
Als de methode van de interface is gedeclareerd als (T), dan implementeren zowel T als *T de interface. Als (*T), dan voldoet alleen *T aan de interface. Dit is cruciaal voor het doorgeven van een struct aan functies die een interface accepteren.
Hoe werkt de "zero value" voor een interface en wat gebeurt er als je een methode aanroept op een nil-waarde?
Een interfacevariabele zonder initialisatie is gelijk aan nil; het proberen om een methode aan te roepen op een nil-veld zal panieken, tenzij er expliciete verwerking van nil-pointer is geïmplementeerd.
Type is gedeclareerd met methoden op pointer (*T), de interface verwacht methoden op waarde (T), en de structuur compileert niet wanneer geprobeerd wordt deze in interfaces te gebruiken. Poging om een methode te declareren voor een variabele van type []User in plaats van voor type User.
Voordelen:
Nadelen:
Alle methoden die interfaces implementeren zijn gedeclareerd met de juiste receiver. Interfaces worden niet gebruikt waar dat niet nodig is (concreet type waar mogelijk, polymorfisme waar nodig).
Voordelen:
Nadelen: