¿Un canal devuelve dos valores?

Vi un código en este enlace y me confundí:http://www.darkcoding.net/software/go-lang-after-four-months/

¿Cuál es el significado del segundo valor (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
        }
    }

}

preguntado el 03 de mayo de 12 a las 19:05

Me parece que es una construcción demasiado pesada. Con select, creo que no hay necesidad de buscar el booleano ok. O me estoy perdiendo algo ? -

son ortogonales. "ok" en la operación de recepción del canal indica si el canal está cerrado. Select solo espera hasta que al menos uno de sus casos pueda ejecutarse, y luego elige uno al azar sin importar si el canal está cerrado. Un caso predeterminado hace que no bloquee. -

4 Respuestas

La variable booleana ok devuelto por un recibir operador indica si el valor recibido se envió en el canal (verdadero) o se devuelve un valor cero porque el canal está cerrado y vacío (falso).

La for bucle termina cuando alguna otra parte del programa Go cierra el fromServer o fromUser canal. En ese caso, una de las sentencias case establecerá ok a la verdad Entonces, si el usuario cierra la conexión o el servidor remoto cierra la conexión, el programa terminará.

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")
}

Respondido el 23 de enero de 16 a las 21:01

¿Qué significa vacío en este caso? Cerrado es fácil, pero ¿vacío significa que nadie está escribiendo en este momento? - Kr0e

@Kr0e Si un canal está cerrado pero aún contiene algunos elementos que es posible recibir de él y ok is true. Pero es imposible escribir en un canal cerrado (de hecho, esta es una definición de "canal cerrado"). Cuando un canal había sido cerrado por el productor goroutine y drenado por el consumidor que ok is false. Vacío y cerrado, como decía. - I159

Un par de respuestas han citado la especificación en el operador de recepción, pero para comprender probablemente necesite leer la especificación en el función de cierre también. Luego, dado que se estará preguntando por qué estas características son como son, lea cómo para declaración rangos sobre un canal. La instrucción for necesita una señal para detener la iteración y close es la forma en que un remitente puede decir "no más datos".

Con close y , ok = <- expuestos como parte del idioma, puede usarlos en otros casos cuando desee que una rutina de envío señale "no más datos". El código de ejemplo en la pregunta es un uso interesante de estas funciones. Está manejando tanto un canal de "servidor" como un canal de "usuario", y si llega una señal de "no más datos" de ya sea de ellos, se sale del bucle.

contestado el 03 de mayo de 12 a las 21:05

Tiene toda la razón. La operación de recepción de valores múltiples devuelve un valor recibido junto con una indicación de si el canal está cerrado. - pase duro

Consulte la sección correspondiente en las especificaciones de idioma de Go: http://golang.org/ref/spec#Receive_operator

contestado el 03 de mayo de 12 a las 20:05

En Go, las funciones y los canales pueden devolver más de 1 valor. Aquí ok debe ser una variable booleana con verdadero (correcto) y falso (incorrecto) y serverData son los datos reales recibidos del canal.

contestado el 03 de mayo de 12 a las 19:05

Esa es la misma construcción para los mapas. - Denys Séguret

Todavía estoy confundido. No entiendo cuando el segundo retorno es falso? Creo que si un canal está vacío, se bloqueará. Y si un canal no está bloqueado, debe volver con éxito. - pase duro

para aclarar eso, supongo que necesitamos ver más del código, es decir, qué está haciendo realmente el canal fromServer, etc. - Caos

@hardPass: devolverá falso si el canal es cerrado y vacío- nuevoacct

@Chaos, estás equivocado. Los canales no pueden recibir ni emitir valores múltiples. - nathan dulce

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.