for - golang float64
¿Cómo se comporta un canal no inicializado? (2)
Este es el comportamiento esperado. Un envío a un canal de bloques nil
para siempre. Puede leer sobre esto en las especificaciones aquí: https://golang.org/ref/spec#Send_statements
Lo mismo también es aplicable para recibir en un canal nil
. ( https://golang.org/ref/spec#Receive_operator )
También puede mantener este enlace a mano para referencia: http://dave.cheney.net/2014/03/19/channel-axioms
Tengo una estructura que contiene un canal que no está inicializado.
Cuando escribo en él, la rutina está bloqueando como se esperaba, pero al lector nunca se le notifica que algo está en la tubería.
Me sorprende que no haya ningún error y me pregunto qué está haciendo Go.
En el ejemplo de abajo, ni el mensaje que se pushed
ni se got it
imprimen. (Descomenta la inicialización y funcionará como un amuleto)
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")
}
Aquí está el patio de recreo https://play.golang.org/p/76zrCuoeoh
(Sé que debo inicializar el canal, este no es el propósito de la pregunta, quiero saber qué está sucediendo en Go con canales no inicializados).
Un campo o variable "no inicializada" de tipo de canal tendrá el valor cero de todos los tipos de canal, que es nil
. Así que vamos a examinar cómo se comportan un canal nil
u operaciones en él.
Vale la pena recopilar los axiomas de canal en una publicación:
- un envío en bloques de canal
nil
para siempre ( Spec: Enviar declaraciones ) - una recepción de un canal
nil
bloquea para siempre ( Spec: operador de recepción ) - un envío a un pánico de canal cerrado ( Spec: Enviar declaraciones )
- una recepción de un canal cerrado devuelve el valor cero de inmediato ( Spec: operador de recepción )
Razonamiento para el bloqueo en caso de canales nil
: si el valor de un canal es nil
, nadie tiene una referencia al mismo, por lo que nadie estará listo para recibir de él (lo que queremos enviar); o enviar algo sobre él (lo que recibiríamos de él).
Puede leer más argumentos y más detalles sobre esto en Dave Cheney: Channel Axioms .
Por completitud:
- Cerrar un canal
nil
provoca un pánico en el tiempo de ejecución (como cerrar un canal ya cerrado). - La longitud y la capacidad de un canal
nil
es0
; de acuerdo connil
rebanadas y mapas que tienen0
longitud y capacidad.
Razonamiento: "cerrado" es un estado, pero un canal nil
no puede tener un estado (solo hay un canal nil
, y no uno para el canal "cerrado" y uno para el canal "no cerrado"). Y no hay elementos en cola en un canal nil
(por lo que len = 0), y no tiene una capacidad de buffer (por lo tanto, cap = 0).