Pierwsza metoda
e1 := Event{Id: 1, Name: "event 1"}
inicjalizuje się zmienną e1
jako wartość z rodzaju Event
. Drugi
e2 := &Event{Id: 1, Name: "event1"}
jest inicjowanie e2
jako wskaźnik do wartości typu Event
Jak podano w komentarzach, zestaw metod zdefiniowany w wartości danego typu są podzbiorem zbioru metod zdefiniowanej na wskaźniku do wartości tego typu. Oznacza to, że jeśli masz metoda
func (e Event) GetName() string {
return e.Name
}
następnie zarówno e1
i e2
może wywołać tę metodę, ale gdybyś miał inną metodę, powiedzieć:
func (e *Event) ChangeName(s string) {
e.Name = s
}
Następnie e1
nie jest w stanie korzystać z ChangeName
metoda, podczas gdy e2
jest.
To (e1
nie jest w stanie wykorzystać metodę ChangeName
, natomiast e2
jest) nie jest (choć może to być w czasie pisania tej pomocy), dzięki @DannyChen za sprowadzenie tego do góry i @GilbertNwaiwu do testowania i zamieszczania w komentarzach poniżej.
(Aby rozwiązać striked z sekcji powyżej:. Zbiór metod określonych w danym typie struct składać z metod określonych dla danego rodzaju i wskaźniki do rodzaju
Zamiast iść teraz automatycznie dereferences argument do metoda, więc jeśli metoda otrzyma wskaźnik, Go wywołuje metodę na wskaźniku do tej struktury, a jeśli metoda otrzyma wartość, Go wywoła metodę na wartość wskazaną przez tę strukturę. W tym momencie moja próba aktualizacja tej odpowiedzi może zabraknąć czegoś ważnego w semantykach, więc jeśli ktoś chciałby to poprawić lub wyjaśnić, nie krępuj się, aby dodać komentarz wskazujący na bardziej wyczerpującą odpowiedź. Oto trochę z placu zabaw ilustrującego ten problem: https://play.golang.org/p/JcD0izXZGz.
W pewnym stopniu ta zmiana sposobu, w jaki wskaźniki i wartości działają jako argumenty dla metod zdefiniowanych dla funkcji, wpływa na niektóre obszary dyskursu poniżej, ale pozostawiam resztę nieedytowaną, chyba że ktoś zachęci mnie do jej aktualizacji, ponieważ wydaje się, że jest bardziej lub mniej poprawne w kontekście ogólnej semantyki języków, które przechodzą przez wartość vs. wskaźnik.)
Odnośnie różnicy między wskaźnikami i wartościami, ten przykład jest przykładowy, ponieważ wskaźniki są zwykle używane w Go, aby umożliwić mutację wartości wskazywane przez zmienną (ale istnieje wiele innych powodów, dla których można również użyć wskaźników! Chociaż w typowym użyciu jest to zwykle solidne założenie). Tak więc, jeśli zdefiniowano ChangeName
zamiast jak:
func (e Event) ChangeName(s string) {
e.Name = s
}
Funkcja ta nie byłaby bardzo przydatna, gdy zwrócił się do odbiornika wartości, jako wartości (nie kursory) nie będzie zachować zmiany, które zostały wprowadzone do nich, jeśli jesteś przeszedł do funkcji. Ma to związek z powierzchni konstrukcji językowych wokół jak zmienne są przypisane i przeszły: What's the difference between passing by reference vs. passing by value?
Można to zobaczyć na tym przykładzie w Go Playground: https://play.golang.org/p/j7yxvu3Fe6
Tego typu konstrukcje są dość podstawowe rzeczy dla Go i wytłumaczył dobrze w Tour of Go (https://tour.golang.org/). A może jeszcze raz przejdziesz przez trasę? – Volker
Jest subtelnie, co nie jest jasne w trakcie trasy. Istnieje różnica w uzyskiwaniu wskaźnika do samej instancji podczas inicjowania struktury. Kiedy i dlaczego miałbym używać VS w jedną stronę. –