¿Por qué Ir de pánico en la escritura de un canal cerrado?

Mientras que uno puede usar el value, ok := <-channel modismo para la lectura de los canales, y por lo tanto el resultado ok puede ser probado por golpear a un canal cerrado:

//reading from closed channel

package main

import "fmt"

func main() {
    ch := make(chan int, 1)
    ch <- 2
    close(ch)

    read(ch)
    read(ch)
    read(ch)
}

func read(ch <-chan int) {
    i,ok := <- ch   
    if !ok {
        fmt.Printf("channel is closed\n")
        return
    }
    fmt.Printf("read %d from channel\n", i)
}

De salida:

read 2 from channel
channel is closed
channel is closed

Ejecutar «la lectura de canal cerrado» en Zona de juegos infantil

Escrito a un posible canal cerrado es más complicado, porque Ir en pánico si usted simplemente tratar de escribir cuando el canal está cerrado:

//writing to closed channel

package main

import (
    "fmt"
)

func main() {
    output := make(chan int, 1) //create channel
    write(output, 2)
    close(output) //close channel
    write(output, 3)
    write(output, 4)
}

//how to write on possibly closed channel
func write(out chan int, i int) (err error) {

    defer func() {
        //recover from panic caused by writing to a closed channel
        if r := recover(); r != nil {
            err = fmt.Errorf("%v", r)
            fmt.Printf("write: error writing %d on channel: %v\n", i, err)
            return
        }

        fmt.Printf("write: wrote %d on channel\n", i)
    }()

    out <- i //write on possibly closed channel

    return err
}

De salida:

write: wrote 2 on channel
write: error writing 3 on channel: send on closed channel
write: error writing 4 on channel: send on closed channel

Ejecutar «escrito canal cerrado» en Zona de juegos infantil

Que yo sepa, no hay un simple modismo para escribir en un posible canal cerrado sin entrar en pánico. ¿Por qué no? ¿Cuál es el razonamiento detrás de un comportamiento asimétrico entre leer y escribir?

  • ¿Cómo podríamos saberlo? Preguntar en google golang grupo, tal vez, uno de los autores le responderemos. No puedo pensar en una razón. Es sólo un buen diseño para cerrar un canal en la parte productora. El pánico te obliga a diseñar la aplicación de tal manera.
  • El cierre de un canal es una señal de que aquí habrá más valores. Escribir en un canal cerrado es un error de programa, que entra en pánico.
InformationsquelleAutor Everton | 2016-01-20

1 Comentario

  1. 15

    De la Vaya Lenguaje De Especificación:

    Para un canal c, la incorporada en función de cierre(c) los registros que no hay más
    valores será enviado en el canal. Es un error si c es una
    canal de recepción solamente. El envío o el cierre de un canal cerrado hace un
    tiempo de ejecución de pánico. El cierre de la nil canal también causa un tiempo de ejecución de pánico.
    Después de llamar a cerrar, y después de cualquier enviadas anteriormente, los valores han sido
    recibido, recibe las operaciones devolverá el valor cero para el
    canal del tipo sin el bloqueo. El multi-valores de operación de recepción
    devuelve un valor recibido, junto con una indicación de si la
    el canal está cerrado.

    Si usted escribe para un canal cerrado, el programa va a entrar en pánico. Usted podría potencialmente detectar este error con recuperar si usted realmente quiere hacer, pero estar en una situación donde usted no sabe si el canal está escrito está abierto es generalmente un signo de un error en el programa.

    Algunas citas:

    Aquí es una motivación:

    Un canal de «cerrar» en realidad es sólo un envío de un especial valor en un
    canal. Es un valor especial que las promesas de que no hay más valores
    ser enviado. Intentando enviar un valor en un canal después de que se ha
    cerrado pánico, ya que en realidad se envía el valor violaría la
    la garantía que ofrece por cerrar. Desde una estrecha es sólo un tipo especial de
    enviar, además, no es permitido después de que el canal ha sido cerrado.

    Aquí es otro:

    El único uso de la canal estrecha es la señal para que el lector que no
    hay más valores que vienen. Que sólo tiene sentido cuando hay un
    única fuente de valores, o cuando varias fuentes de coordenadas. Allí
    no es razonable, programa en el que varios goroutines cerca de un canal
    sin la comunicación. Eso implicaría que varios goroutines
    sabe que no hay más valores a enviar–¿cómo podrían
    determinar que si ellos no se comunican?

    (Ian Lance Taylor)

    Aquí es otro:

    El cierre de un canal libera como un recurso. No tiene más sentido
    cerca de un canal que varias veces se hace para cerrar un archivo
    descriptor varias veces, o liberar un bloque de memoria asignada
    en múltiples ocasiones. Tales acciones implican el código está roto, por
    el cierre de un canal cerrado desencadena un ataque de pánico.

    (Rob Pike)

    Fuente: Ir a diseño de detalle de la justificación de la pregunta – canal cerca de

Dejar respuesta

Please enter your comment!
Please enter your name here