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 ?

Author: flyingfinger, 2013-05-16

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
}
 48
Author: beatgammit,
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.

 6
Author: newacct,
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ą.

 1
Author: cthom06,
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.

 1
Author: zzzz,
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