2012-05-03 11 views
14

Widziałem niektóre kodu w ten link i irytować: http://www.darkcoding.net/software/go-lang-after-four-months/Czy kanał Go zwraca dwie wartości?

Co to ma znaczyć drugiej wartości (ok)?

for self.isRunning { 

    select { 
    case serverData, ok = <-fromServer: // What's the meaning of the second value(ok)? 
     if ok { 
      self.onServer(serverData) 
     } else { 
      self.isRunning = false 
     } 

    case userInput, ok = <-fromUser: 
     if ok { 
      self.onUser(userInput) 
     } else { 
      self.isRunning = false 
     } 
    } 

} 
+0

Wydaje mi się, że to zbyt ciężka konstrukcja. Z select, myślę, że nie ma potrzeby pobierania ok boolean. Czy może czegoś brakuje? –

+1

Są ortogonalne. "ok" w operacji odbierania kanału wskazuje, czy kanał jest zamknięty. Wybierz tylko czeka, aż przynajmniej jeden z jego przypadków będzie mógł zostać uruchomiony, a następnie zostanie wybrany losowo, bez względu na to, czy kanał jest zamknięty. Domyślny przypadek powoduje, że nie jest blokowany. – SteveMcQwark

Odpowiedz

14

Wartość logiczna zmienna ok zwracane przez receive operator wskazuje, czy otrzymana wartość została wysłana na kanale (true), czy jest to wartość zerowa zwrócony ponieważ kanale jest zamknięty i pusty (fałsz).

Pętla for kończy się, gdy inna część programu Go zamyka kanał fromServer lub fromUser. W takim przypadku jedna z instrukcji sprawi, że ok stanie się prawdziwe. Jeśli więc użytkownik zamknie połączenie lub serwer zdalny zamknie połączenie, program zostanie zakończony.

http://play.golang.org/p/4fJDkgaa9O:

package main 

import "runtime" 

func onServer(i int) { println("S:", i) } 
func onUser(i int) { println("U:", i) } 

func main() { 
    fromServer, fromUser := make(chan int),make(chan int) 
    var serverData, userInput int 
    var ok bool 

    go func() { 
     fromServer <- 1 
     fromUser <- 1 
     close(fromServer) 
     runtime.Gosched() 
     fromUser <- 2 
     close(fromUser) 
    }() 

    isRunning := true 
    for isRunning { 
     select { 
      case serverData, ok = <-fromServer: 
       if ok { 
        onServer(serverData) 
       } else { 
        isRunning = false 
       } 

      case userInput, ok = <-fromUser: 
       if ok { 
        onUser(userInput) 
       } else { 
        isRunning = false 
       } 
      } 
     } 
     println("end") 
} 
+0

Co znaczy pusty w tym przypadku? Zamknięte jest łatwe, ale czy puste oznacza, że ​​nikt nie pisze w tej chwili? – Kr0e

+0

@ Kr0e Jeśli kanał jest zamknięty, ale nadal zawiera pewne elementy, można z niego odebrać, a "ok" to "true". Ale nie można pisać na zamkniętym kanale (w rzeczywistości jest to definicja "zamkniętego kanału"). Kiedy kanał został zamknięty przez producenta goroutine i odsączony przez konsumenta niż "ok" jest "fałszem". Pusty i zamknięty, tak jak powiedział. – I159

-1

W trybie Go funkcje & kanały mogą zwracać więcej niż 1 wartość. Tutaj ok musi być zmienną typu boolean z prawdą (udane) i fałszywą (bez powodzenia), a data serwera jest faktycznymi danymi otrzymanymi z kanału.

+3

To ta sama konstrukcja dla map. –

+0

Nadal jestem zdezorientowany. Nie rozumiem, kiedy drugi powrót jest fałszywy? Myślę, że jeśli kanał jest pusty, zostanie zablokowany. A jeśli kanał nie jest blokowany, musi pomyślnie powrócić. – hardPass

+0

, aby wyjaśnić, że, myślę, że musimy zobaczyć więcej kodu, tj. Jaki jest kanał z serwera tak naprawdę robi, itd .. – Chaos

8

Kilka odpowiedzi zostały przywołane spec od operatora odbierać, ale aby zrozumieć, prawdopodobnie trzeba czytać spec na close function również. Skoro zastanawiasz się, dlaczego te funkcje są takie, jakie są, przeczytaj, jak zakres for statement sięga po kanał. Instrukcja for potrzebuje sygnału do zatrzymania iteracji, a close jest sposobem, w jaki nadawca może powiedzieć "brak więcej danych".

Wyeksponowane jako część języka, można używać ich w innych przypadkach, gdy chcemy, aby wysyłający goroutine sygnalizował "brak danych". Przykładowy kod w pytaniu jest interesującym wykorzystaniem tych funkcji. Obsługuje zarówno kanał "serwerowy", jak i kanał "użytkownika", a jeśli sygnał "brak więcej danych" przybywa z albo z nich, to wychodzi z pętli.

+0

Masz całkowitą rację.Wielowartościowa operacja odbioru zwraca odebraną wartość wraz ze wskazaniem, czy kanał jest zamknięty. – hardPass

Powiązane problemy