Są kanałami przekazywanymi przez odniesienie
The Go tour ma taki przykład dla kanałów: https://tour.golang.org/concurrency/2
package main
import "fmt"
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
func main() {
a := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(a[:len(a)/2], c)
go sum(a[len(a)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y)
}
Kanał c jest modyfikowany w funkcji sum i zmiany utrzymują się po zakończeniu funkcji. OczywiĹ "cie c zostaĹ' o przekazane przez referencjÄ™, ale nie zostaĹ ' stworzony wskaĺşnik do C. Czy kanały są domyślnie przekazywane przez odniesienie w go ?
4 answers
technicznie są kopiowane, ponieważ kiedy używasz make
, przydzielasz coś na stertę, więc jest to technicznie wskaźnik za kulisami. Ale typ wskaźnika nie jest odsłonięty, więc można go traktować jako typ odniesienia.
EDIT : From the spec:
Wbudowana funkcja make przyjmuje typ T, który musi być typem wycinka, mapy lub kanału, opcjonalnie po którym następuje lista wyrażeń specyficznych dla danego typu. Zwraca wartość typu T (nie *t). Pamięć jest inicjalizowana w sposób opisany w sekcji o wartościach początkowych.
Kanał musi zostać zainicjowany, zanim będzie mógł zostać użyty. Make robi to, więc może być używany jako typ odniesienia.
Oznacza to, że możesz przekazać ją do funkcji i zapisać do niej lub odczytać z niej. Ogólna zasada jest taka, że jeśli używasz make
, new
lub &
, można przekazać go do innej funkcji bez kopiowania danych bazowych.
Oto " odniesienie" rodzaje:
- plastry
- mapy
- kanały
- wskaźniki
- funkcje
Tylko typy danych (liczby, Boole i struktury, itp.) są kopiowane podczas przechodzenia do funkcji. Łańcuchy są specjalne, ponieważ są niezmienne, ale nie przekazywane przez wartość. Oznacza to, że następujące działania nie będą działać zgodnie z oczekiwaniami:
type A struct {
b int
}
func f(a A) {
a.b = 3
}
func main() {
s := A{}
f(s)
println(s.b) // prints 0
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-16 14:43:13
Wszystko W Go jest przekazywane i przypisywane przez wartość. Niektóre wbudowane typy, w tym typy kanałów i typy map, zachowują się jak nieprzezroczyste wskaźniki do jakiejś ukrytej struktury wewnętrznej. I można modyfikować tę wewnętrzną strukturę poprzez operacje na kanale lub mapie. Zaczynają się jako nil
, co jest analogiczne do wskaźnika nil
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-18 00:17:21
Można powiedzieć tak, ale stwierdzenie "kanał c jest modyfikowany w funkcji sum" nie jest poprawną terminologią. Kanały wysyłane i odbierane nie są tak naprawdę uważane za modyfikacje.
Zauważ, że plastry i mapy zachowują się w podobny sposób, zobacz http://golang.org/doc/effective_go.html Po Więcej Szczegółów.
Również "przekazywane przez odniesienie" oznacza, że przypisanie może być wykonane do c
w sum
, które zmieniłoby jego wartość (w przeciwieństwie do jego podstawowych danych) poza sumy, co nie jest prawdą.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-16 14:31:15
Zmienne kanału są odniesieniami, ale zależy to od twojej definicji 'odniesienia'. specyfikacja języka nigdy nie wspomina o typach odniesienia.
Żaden kanał (zmienna) nie jest 'zmodyfikowany' w funkcji sum
. Wysyłanie do kanału zmienia jego stan.
Innymi słowy, tak Kanał jest zaimplementowany jako wskaźnik do pewnej struktury czasu pracy. Zauważ, że jest to absolutnie niezbędne dla semantyki referencyjnej.
EDIT: powyższe zdanie miało brzmieć: "zauważ, że to jest Nie ściśle niezbędne dla semantyki odniesienia.", tj. słowo " nie " zniknęło. Przepraszam za ewentualne nieporozumienie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-19 11:07:13