ProgrammatieGo ontwikkelaar

Leg de bijzonderheden van de ingebouwde functie make in Go uit: wanneer is deze nodig, hoe werkt het snijden en initialiseren voor map, slice en channel? Welke fouten komen voor door onjuist gebruik van make en new?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

De functie make in Go wordt uitsluitend gebruikt voor het initialiseren van objecten van de typen: slice, map en channel. Het reserveert de benodigde datastructuur en retourneert een gebruiksklaar object (geen pointer!).

Voorbeelden:

s := make([]int, 5, 10) // slice van lengte 5, capaciteit 10 m := make(map[string]int) // lege map ch := make(chan int, 2) // gebufferde channel met 2

Fijnere punten:

  • Voor slice zijn de parameters: lengte (len) en (optioneel) capaciteit (cap).
  • Voor map en chan — alleen (optionele) capaciteit (initieel formaat/buffer).
  • De functie make retourneert al een geconfigureerd object, klaar voor gebruik.
  • Voor andere typen (struct, array) wordt make niet gebruikt, deze worden geïnitialiseerd met behulp van literalen of new (dat een pointer naar de zero value retourneert).

Vergelijking met new:

  • new(T) retourneert *T, waarbij alle velden nullen zijn.
  • make(T) retourneert T alleen voor drie typen: slice, map, chan.

Misleidende vraag

Kun je een werkende map krijgen via new in plaats van make?

m := new(map[string]int) (*m)["a"] = 1 // Wat gebeurt er?

Velen denken dat dit correct is, maar er zal een panic optreden tijdens runtime: assignment to entry in nil map. Omdat de variabele *m nil bevat!

Juist: gebruik make:

m := make(map[string]int) m["a"] = 1 // OK

Voorbeelden van echte fouten door onbekendheid met de nuances van dit onderwerp


Verhaal

In een microservice voor het opslaan van een cache werd een map gemaakt via var cache map[string]interface{} zonder initialisatie met make, waardoor er een panic optrad bij het schrijven in productie met onduidelijke stack traces. Het probleem werd pas gevonden na code-analyse: de map was nil.


Verhaal

Bij het schrijven van een datastream werd vergeten om de buffer bij de channel en werd deze gemaakt via make(chan int). Het gevolg was dat goroutines vastlopen in afwachting van lezen, terwijl een asynchrone uitwisseling verwacht werd. De fout werd pas opgemerkt tijdens een grootschalige test.


Verhaal

In een project waar initialisatie gebeurde via new, probeerden sommige ontwikkelaars new([]int) te gebruiken in plaats van make([]int, 10), waardoor ze een pointer op een nil slice kregen en een runtime panic bij de eerste schrijfpogingen.