Lecții din modul (1/5)
Interfețe: definirea unui comportament
O interfață în Go este un set de semnături de metodă. O valoare
implementează interfața dacă are toate acele metode — nu
implements, fără extends, fără înregistrare explicită. Este
model numit adesea „tastare structurală” sau „dactilare statică de rață”:
compilatorul verifică conformitatea în momentul compilării, dar pe baza
forma, nu pe declarații.
Declararea unei interfețe
type Greeter interface {
Greet() string
}Convenție: nume care se termină în -er pentru interfețele cu o singură metodă
(Reader, Writer, Stringer, Closer). Interfețe mici
(1–2 metode) sunt idiomatice: biblioteca standard este plină de
interfețe minuscule care compun împreună (io.ReadWriter,
io.ReadCloser, …).
Implementare implicită
type Person struct{ Name string }
func (p Person) Greet() string {
return "ciao " + p.Name
}
// Person satisfies Greeter because it has the required method.
var s Greeter = Person{Name: "Ada"}
fmt.Println(s.Greet())Niciun cuvânt cheie. Dacă tipul are metode, acesta poate fi atribuit o variabilă de tipul respectiv de interfață. Asta este.
Polimorfism prin interfață
type Robot struct{ ID string }
func (r Robot) Greet() string { return "bip " + r.ID }
func greet(s Greeter) {
fmt.Println(s.Greet())
}
greet(Person{Name: "Ada"})
greet(Robot{ID: "R2"})greet acceptă orice tip care satisface Greeter. Aceasta este calea Go
de a face polimorfism: fără ierarhii, doar capacitate.
Interfața goală
var x interface{} = 42
var y any = "ciao" // any is the built-in alias of interface{}interface{} (sau any din Go 1.18) nu necesită metode, deci orice
valoarea o satisface. Util pentru containere generice, dar pentru extragere
valoarea concretă de care aveți nevoie de o aserțiune de tip sau comutator de tip
(lecțiile următoare).
Set de metode: valoare vs receptor pointer (previzualizare)
Reamintim din modulul 5:
- Metodele cu un receptor de valori sunt în setul de metode atât
T, cât și*T. - Metodele cu un receptor pointer sunt NUMAI în setul de metode
*T.
Consecință practică:
type Counter struct{ N int }
func (c *Counter) Inc() { c.N++ }
type Incrementer interface { Inc() }
var i Incrementer = &Counter{} // OK: *Counter has Inc()
// var j Incrementer = Counter{} // ERROR: Counter (value) does NOTCând o metodă are un receptor pointer, trebuie să îi alocați un pointer variabila de interfață.
Încearcă
Definiți o interfață Greeter cu o singură metodă și șir Greet().
Afișează indiciu
Sintaxă: `type Name interface { Method(args) return }`.
Soluție disponibilă după 3 încercări
Implementați Greeter pe un robot de tip nou cu șir de câmp ID; metoda returnează „bip” + ID.
Afișează indiciu
Fără „implemente”: definiți doar metoda cu semnătura corectă.
Soluție disponibilă după 3 încercări
Cum declari că tipul P implementează interfața Greeter?
type P struct{}
// ?Recapitulare
- Interfață = set de semnături de metodă; nu
implements. - Implementare implicită: trebuie doar să aveți metodele cu semnătura potrivită.
- Idiomatic: interfețe mici (1–2 metode), nume în
-er. interface{}/any: acceptă orice valoare, pierde siguranța tipului.- Set de metode: receptor pointer → doar
*Tsatisface interfața. - Go polymorphism: parametri tipați pe interfață, fără ierarhii.