programowanieProgramista Backend

Jak działa praca z danymi o niezmiennej (immutable) i zmiennej (mutable) strukturze w Go? Podaj przykłady, gdzie ma to znaczenie w programowaniu.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

W Go większość wbudowanych typów danych (np. int, float, struct) — są zmienne, jeśli są zadeklarowane jako zmienne, ponieważ przy przekazywaniu przez wartość kopiowana jest cała struktura lub wartość. Jednak jest pewna subtelność: slice, map, kanały — to typy referencyjne z ich własną logiką przechowywania danych.

Typy podstawowe:

x := 10 y := x // Tutaj tworzona jest kopia wartości, x i y nie są ze sobą powiązane y = 20 // x pozostanie 10

Slice:

a := []int{1,2,3} b := a // odniesienie do tej samej podstawowej "podłoża" tablicy b[0] = 100 // teraz a[0] == 100

To jest ważne, jeśli funkcja lub metoda przyjmuje strukturę lub slice, ponieważ zmiany mogą albo dotknąć oryginalnych danych, albo nie, w zależności od typu danych i sposobu przekazywania (przez wartość lub przez referencję).

Pytanie podchwytliwe

Pytanie: "Jeśli przypiszesz jeden slice do drugiego, czy otrzymujesz głęboką kopię, czy obie wskazują na te same dane?"

Odpowiedź: Przy prostym przypisaniu slice (b := a) — obie wskazują na tę samą podstawową tablicę, ale mają niezależne długość i pojemność. Zmiana przez jeden z slice'ów danych samej tablicy jest widoczna w drugim.

Przykład:

a := []int{1,2,3} b := a b[0] = 42 fmt.Println(a) // [42 2 3]

Aby wykonać głęboką kopię, używa się copy:

c := make([]int, len(a)) copy(c, a) c[0] = 99 fmt.Println(a) // [42 2 3], c — niezależna kopia

Historia

Usługa filtrowania danych zaczęła zwracać nieoczekiwane wyniki: Jeden deweloper przekazywał slice między kilkoma funkcjami bez kopiowania, zmieniając ich stan. Z powodu modyfikacji slice'ów w różnych miejscach logika aplikacji łamała się, pojawiały się dziwne błędy w danych, które długo nie mogły zostać uchwycone.


Historia

Utrata danych po przekazaniu struktury: W jednym projekcie podczas serializacji danych przez przypadek usunięto z struktury obowiązkowe pole, ponieważ obiekt był przekazywany przez referencję, a nie tworzono jego kopii. W rezultacie z powodu tego traciła się krytyczna informacja w produkcji.


Historia

Błąd równoczesnej pracy z mapą: Deweloper skopiował referencję do mapy, myśląc, że zmiany nie wpłyną na oryginał, jak to ma miejsce w innych językach. W rezultacie wystąpiły wyścigi danych podczas pracy w różnych gorutynach, co doprowadziło do awarii aplikacji.