2012-05-03 13 views
14

Ho visto del codice in questo collegamento e mi sono confuso: http://www.darkcoding.net/software/go-lang-after-four-months/Il canale di un Go restituisce due valori?

Qual è il significato del secondo valore (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

Mi sembra un costrutto troppo pesante. Con select, penso che non ci sia bisogno di recuperare l'ok booleano. O mi sta sfuggendo qualcosa ? –

+1

Sono ortogonali. "ok" nell'operazione di ricezione del canale indica se il canale è chiuso. Selezionare aspetta solo fino a quando almeno uno dei suoi casi può essere eseguito, quindi ne sceglie uno a caso indipendentemente dal fatto che il canale sia chiuso. Un caso predefinito lo rende non bloccante. – SteveMcQwark

risposta

14

La variabile booleana ok restituito da una receive operator indica se il valore ricevuto è stato inviato sul canale (true) o è un valore pari a zero restituito perché il canale è chiuso e vuoto (falso).

Il ciclo for termina quando un'altra parte del programma Go chiude il canale fromServer o fromUser. In tal caso, una delle dichiarazioni del caso imposta ok su true. Quindi, se l'utente chiude la connessione o il server remoto chiude la connessione, il programma terminerà.

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

Cosa significa vuoto in questo caso? Chiuso è facile ma vuol dire che nessuno sta scrivendo in questo momento ?? – Kr0e

+0

@ Kr0e Se un canale è chiuso ma contiene ancora alcuni elementi è possibile ricevere da esso e 'ok' è' true'. Ma è impossibile scrivere su un canale chiuso (di fatto si tratta di una definizione di "canale chiuso"). Quando un canale è stato chiuso dalla goroutine del produttore e svuotato dal consumatore che 'ok' è' false'. Vuoto e chiuso, proprio come ha detto. – I159

-1

In Go, le funzioni & canali possono restituire più di 1 valore. Qui ok deve essere una variabile booleana con vero (riuscito) e falso (non riuscita) e serverData sono i dati effettivi ricevuti dal canale.

+3

È lo stesso costrutto per le mappe. –

+0

Sono ancora confuso. Non capisco quando il secondo ritorno è falso? Penso che se un canale è vuoto, bloccherà. E se un canale non è un blocco, deve restituirlo correttamente. – hardPass

+0

per chiarire che, suppongo che abbiamo bisogno di vedere più del codice, cioè cosa sta facendo il canale dal server in realtà, ecc. – Chaos

8

Un paio di risposte hanno citato la specifica sull'operatore ricevere, ma per capire che probabilmente bisogno di leggere le specifiche sulla close function pure. Quindi, dal momento che ti starai chiedendo perché queste funzionalità sono così come sono, leggi come gli intervalli for statement si sovrappongono a un canale. L'istruzione for ha bisogno di un segnale per interrompere l'iterazione e close è il modo in cui un mittente può dire "non più dati".

Con close e , ok = <- esposto come parte del linguaggio, è possibile utilizzarli in altri casi in cui si desidera un goroutine invio per segnalare "non più di dati". Il codice di esempio nella domanda è un uso interessante di queste funzionalità. Gestisce sia un canale "server" che un canale "utente" e se un segnale "nessun altro dato" arriva da o da, si interrompe.

+0

Hai perfettamente ragione.L'operazione di ricezione multivalore restituisce un valore ricevuto insieme all'indicazione se il canale è chiuso. – hardPass

Problemi correlati