ProgrammatieGo ontwikkelaar

Wat zijn de ingebouwde functies append, len en cap in Go, hoe werken ze op taalniveau, en welke verborgen gevaren met slices zijn er verbonden aan hun gebruik?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

In Go spelen de ingebouwde functies append, len en cap een sleutelrol bij het werken met slices.

  • len(slice) retourneert het aantal elementen in de slice.
  • cap(slice) retourneert de capaciteit van de slice - het maximale aantal elementen voordat er nieuwe geheugentoewijzing plaatsvindt.
  • append(slice, elems ...T) leidt bij onvoldoende capaciteit tot de creatie van een nieuwe array (en dus een nieuwe onderliggende opslag), wat de semantiek van de slice-doorvoer onverwacht kan veranderen.

Voorbeeld:

arr := []int{1,2,3} arr2 := append(arr, 4) // arr2 kan dezelfde of een nieuwe backing array zijn, afhankelijk van cap(arr)

Fijnere punten:

  • Als je append toevoegt aan een slice die "afgekapt" is van een andere slice (of de oorspronkelijke array), kan er een side-effect optreden: wijziging van de oorspronkelijke gegevens.
  • Bij het doorgeven van slices aan functies, werken len/cap alleen op het "zichtbare" deel.
  • Bij append die cap overschrijdt, wordt een nieuwe array gecreëerd, de oude blijft ongemoeid.

Misleidende vraag

Wat gebeurt er als je een stuk van de slice "afsnijdt" en een element toevoegt met append? Heeft dit invloed op de oorspronkelijke array?

Antwoord: Als de cap het toelaat, schrijft append het element "aan de staart" van de oorspronkelijke array, en wijzigingen zijn zichtbaar via alle slices die naar dezelfde array verwijzen.

Voorbeeld:

a := []int{1,2,3,4} b := a[:2] // [1 2], len=2, cap=4 b = append(b, 10) // a verandert: a -> [1, 2, 10, 4]

Voorbeelden van echte fouten


Verhaal

In het team werden elementen aan een dochter-slice toegevoegd, en plotseling veranderden de gegevens in de ouder-array - dit veroorzaakte inconsistentie in de businesslogica en complexe bugs die moeilijk te debuggen waren in de taakverdeling tussen gebruikers.


Verhaal

Bij het opnieuw aanroepen van append op een grote slice werd verwacht dat er altijd een nieuwe array zou worden toegewezen, maar in werkelijkheid werkten verschillende delen van het systeem met dezelfde "backing array", wat racecondities en datacorruptie veroorzaakte.


Verhaal

Een ontwikkelaar maakte een slice van vaste grootte met help van make, maar maakte een fout en verwisselde de argumenten: make([]int, cap, len). Dit resulteerde erin dat de logica, gericht op capaciteit, onverwacht op lengte werkte, wat paniek veroorzaakte bij overschrijding van s[0:len].