ProgrammazioneSviluppatore Go

Come funzionano i metodi per le strutture in Go? Qual è la differenza tra la dichiarazione di un metodo e una funzione, e come sono implementati i metodi per i tipi basati su alias (type alias)?

Supera i colloqui con l'assistente IA Hintsage

Risposta

In Go, i metodi sono funzioni con un receiver (ricevente) che indica a quale tipo appartiene il metodo:

type User struct { Name string } func (u *User) SayHello() { fmt.Println("Ciao,", u.Name) }
  • Il metodo è associato a un tipo specifico (ad esempio, User), mentre la funzione non lo è.
  • Il ricevente del metodo ((u *User)) funziona come il primo argomento in una funzione, ma la sintassi e le chiamate sono diverse.

Importante! I metodi possono essere dichiarati solo per tipi definiti nel proprio pacchetto (no methods on type defined in other package, incl. built-in types). Il comportamento con gli alias (type alias) è speciale:

  • Per nuovi tipi basati su tipi esistenti (type MyInt int) — è possibile aggiungere metodi.
  • Per type alias (type MyInt = int) — non è possibile aggiungere metodi, perché è solo un alias.

Esempio:

type MyInt int func (m MyInt) Double() int { return int(m) * 2 } // Type alias type MyIntAlias = int // func (m MyIntAlias) Double() int { ... } // errore di compilazione

Domanda trabocchetto

È possibile dichiarare un metodo per uno slice di tipo []int o per un type alias?

Risposta: Per uno slice di tipo built-in ([]int) non è possibile dichiarare metodi. Per un nuovo tipo personalizzato basato su uno slice — si può:

type MySlice []int func (s MySlice) Sum() int { ... } // consentito

Per un type alias non è possibile:

type SuperSlice = []int // func (s SuperSlice) Sum() int { ... } // errore

Esempi di errori reali a causa della mancata conoscenza delle sottigliezze dell'argomento


Storia

Nel progetto di microservizi, il team ha definito un type alias per int64 (per gli identificatori) e ha provato a dichiarare metodi di validazione direttamente per esso — il codice non si compilava, è stato necessario rifattorizzare tutte le strutture per supportare i metodi.

Storia

Nel progetto backend, hanno scritto metodi per uno slice personalizzato, ma accidentalmente non hanno definito un nuovo tipo (type ... []T), e hanno lavorato con il built-in []T, motivo per cui non sono riusciti ad aggiungere alcun metodo per lavorare con gli elementi dello slice.

Storia

Cercando di aggiungere metodi ai tipi di un pacchetto esterno (ad esempio, time.Time) per standardizzare il lavoro con le date, si è scoperto che non è possibile in Go — è stato necessario utilizzare la composizione e funzioni utility.