2016-08-18 89 views
5

Mam strukturę, która posiada kanał, który nie został zainicjowany.Jak zachowuje się kanał nie zainicjowany?

Kiedy zapisuję w nim, procedura jest blokowana zgodnie z oczekiwaniami, ale czytelnik nigdy nie otrzymuje powiadomienia, że ​​coś jest w rurze.

Jestem zaskoczony, że nie ma błędu i zastanawiam się, co robi Go.

W poniższym przykładzie nie są drukowane ani wiadomości pushed ani. (Odkomentuj intialization i będzie działać jak czar)

type MyStruct struct { 
    over chan bool 
} 

func main() { 
    nonInitialized := &MyStruct{} 
    // nonInitialized.over = make(chan bool) 
    go func() { 
     for i := 0; i < 10; i++ { 
      select { 
      case <-nonInitialized.over: 
       fmt.Println("got it") 
      default: 
       // proceed 
      } 
      fmt.Println("do some stuff") 
      time.Sleep(10 * time.Millisecond) 
     } 
     panic("took too long") 
    }() 
    // push on the non initialized channel 
    fmt.Println("pushing") 
    nonInitialized.over <- true 
    fmt.Println("pushed") 
} 

Oto zabaw https://play.golang.org/p/76zrCuoeoh

(wiem powinna zainicjować kanał, to nie jest cel pytanie, chcę wiedzieć co się dzieje w Go z niezainicjowanymi kanałami.)

Odpowiedz

7

Określenie „niezainicjowany” pola lub zmienna channel type będzie miał zero value wszystkich typów kanałów, co jest nil. Zbadajmy więc, jak zachowuje się kanał lub jego operacje na kanale nil.

Warto zbieranie aksjomaty kanału w jednym poście:

uzasadnienie blokowania w przypadku nil kanałów: jeśli wartość kanału jest nil, nikt nie ma odniesienie do niego, więc nikt nigdy nie będzie gotowy otrzymywać z niego (to, co chcemy wysłać); lub wyślij na nią cokolwiek (co byśmy od niego otrzymali).

Możesz przeczytać dalsze argumenty i więcej szczegółów na ten temat w Dave Cheney: Channel Axioms.

Dla kompletności:

  • Closingnil kanału powoduje run-time panic (podobnie jak zamknięcie już zamkniętego kanału).
  • Length and capacity kanału jest 0; zgodnie z nil plastrami i mapami mającymi długość i pojemność 0.

Rozumowanie: „zamknięty” jest stanem, ale nil kanał nie może mieć stan (jest tylko jeden nil kanał, a nie jeden za „zamknięte” i jeden dla „nie” zamkniętym kanale). I nie ma żadnych elementów oczekujących w kanale nil (więc len = 0) i nie ma on pojemności bufora (więc cap = 0).