2016-10-12 35 views
13

W Golang próbuję utworzyć funkcję plasterka dla mojego problemu z komiwojażera. Robiąc to, zauważyłem, że gdy zacząłem edytować plaster, dałem, że funkcja mieszania była inna za każdym razem, gdy ją przekazywałem.Czy plasterki golang przechodzą przez wartość?

Po pewnym debugowaniu dowiedziałem się, że to przeze mnie edytowanie plasterka wewnątrz funkcji. Ale ponieważ Golang ma być językiem "przekazywać wartości", jak to możliwe?

https://play.golang.org/p/mMivoH0TuV

mam pod warunkiem link zabaw, aby pokazać, co mam na myśli. Po usunięciu linii 27 otrzymasz inne wyjście niż pozostawienie go, nie powinno to mieć znaczenia, ponieważ funkcja powinna tworzyć własną kopię przekroju, gdy zostanie przekazana jako argument.
Czy ktoś może wyjaśnić to zjawisko?

Odpowiedz

28

Tak, wszystko w Go jest przekazywane według wartości. Plastry też. Ale wartością przekroju jest nagłówek, opisujący ciągłą sekcję tablicy pomocniczej, a wartość przekroju zawiera tylko wskaźnik do tablicy, w której elementy są faktycznie przechowywane. Wartość slice nie zawiera elementów (w przeciwieństwie do tablic).

Tak więc po przekazaniu plasterka do funkcji zostanie wykonana kopia tego nagłówka, w tym wskaźnik, który wskaże tę samą tablicę podkładową. Modyfikowanie elementów plasterka implikuje modyfikowanie elementów tablicy podkładu, a więc wszystkie plasterki, które mają tę samą tablicę podkładową, "obserwują" zmianę.

Aby zobaczyć, co jest w nagłówku segmentu, sprawdź rodzaj reflect.SliceHeader:

type SliceHeader struct { 
    Data uintptr 
    Len int 
    Cap int 
} 

zobacz sekcję/możliwy duplikat pytanie: Are Golang function parameter passed as copy-on-write?

Przeczytaj wpis na blogu: Go Slices: usage and internals

+0

więc rozwiązanie być wykonaniem lokalnej kopii plasterka wewnątrz funkcji. i zamiast tego edytować? – duck

+1

@ user4901806 Jeśli nie chcesz modyfikować elementów przekazanego plasterka (elementy tablicy podkładu wskazuje na), a następnie tak, utwórz kopię. – icza

+0

Zakładam, że oznaczałoby to, że jeśli dodamy element, nie zostanie on dodany do oryginalnego plasterka. – Sahas