In Go zijn de meeste ingebouwde gegevenstypen (zoals int, float, struct) - veranderlijk, als ze als variabelen zijn gedeclareerd, omdat bij doorgeven bij waarde de hele structuur of waarde wordt gekopieerd. Maar er is een nuance: slices, maps, channels zijn referentietypen met hun eigen interne logica voor gegevensopslag.
Basis types:
x := 10 y := x // Hier wordt een kopie van de waarde gemaakt, x en y zijn niet met elkaar verbonden y = 20 // x blijft 10
Slices:
a := []int{1,2,3} b := a // verwijzing naar dezelfde basale "ondergrond" van de array b[0] = 100 // nu is ook a[0] == 100
Dit is belangrijk als een functie of methode een struct of slice accepteert, omdat wijzigingen de originele gegevens kunnen beïnvloeden of niet, afhankelijk van het gegevenstype en de manier van doorgeven (bij waarde of bij referentie).
Vraag: "Als je de ene slice aan de andere toewijst, krijg je dan een diepe kopie of wijzen ze beide naar dezelfde gegevens?"
Antwoord: Bij eenvoudige toewijzing van slices (b := a) - wijzen ze beide naar dezelfde basale array, maar hebben onafhankelijke lengte en capaciteit. Wijzigingen via een van de slices in de eigenlijke array zijn zichtbaar in de andere.
Voorbeeld:
a := []int{1,2,3} b := a b[0] = 42 fmt.Println(a) // [42 2 3]
Om een diepe kopie te maken, wordt copy gebruikt:
c := make([]int, len(a)) copy(c, a) c[0] = 99 fmt.Println(a) // [42 2 3], c is een onafhankelijke kopie
Verhaal
Een gegevensfilterdienst begon onverwachte resultaten terug te geven: Een ontwikkelaar gaf slices door tussen verschillende functies zonder te kopiëren, waardoor ze hun staat wijzigden. Vanwege de wijzigingen aan de slices op verschillende plaatsen brak de logica van de applicatie, en er werden vreemde bugs in de gegevens gevonden die moeilijk te traceren waren.
Verhaal
Gegevensverlies na het doorgeven van een struct: In een project werd per ongeluk een verplicht veld uit de struct verwijderd tijdens de serialisatie, omdat het object via een referentie werd doorgegeven en geen kopie werd gemaakt. Dit leidde tot het verlies van kritische informatie in productie.
Verhaal
Fout bij parallelle werking met map: Een ontwikkelaar kopieerde de referentie naar de map, denkend dat wijzigingen geen invloed zouden hebben op het origineel, zoals in andere talen vaak het geval is. Hierdoor ontstond een datarace bij het werken in verschillende goroutines, wat leidde tot crashes van de applicatie.