English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Golang 基础教程

Golang 控制语句

Golang 函数 & 方法

Golang 结构体

Golang 切片 & 数组

Golang 字符串(String)

Punteros de Golang

Interfaces de Golang

Concurrencia de Golang

Excepciones (Error) de Golang

Misceláneos de Golang

Select de Go y bucle muerto

En el lenguaje Go, la declaración select es comoSentencia switchpero en la declaración select, la sentencia case se refiere a la comunicación, es decir, las operaciones de envío o recepción en el canal.

Sintaxis:

select{
    case SendOrReceive1: // Sentencia
    case SendOrReceive2: // Sentencia
    case SendOrReceive3: // Sentencia
    ......
    default: // Sentencia
 }

En este artículo, aprenderemos a evitar el bucle muerto utilizando el caso por defecto. Pero primero, entendamos qué es un bucle muerto?

Bucle muerto:Cuando intenta leer o escribir datos en un canal pero no hay valor en el canal. Por lo tanto, bloquea la ejecución actual de la goroutine y transfiere el control a otra goroutine, pero si no hay otra goroutine disponible o si otras goroutines están dormidas debido a esta condición, el programa se colapsará. Este fenómeno se llama bucle muerto. Como se muestra en el siguiente ejemplo:

package main
func main() {
    //Crear canal
    //El bucle muerto ocurre porque no hay goroutines escribiendo
    //Por lo tanto, la declaración select se bloquea permanentemente
    c := make(chan int)
    select {
    case <-c:
    }
}

Salida:

error fatal: todas las goroutines están dormidas - ¡bloqueo!
goroutine 1 [canal recibir]:
main.main()

Para evitar esto, utilizamos el caso por defecto en la declaración select. En otras palabras, cuando ocurre un bucle muerto en el programa, se ejecuta el caso por defecto de la declaración select para evitar el bucle muerto. Como se muestra en el siguiente ejemplo, utilizamos el caso por defecto en la declaración select para evitar el bucle muerto.

package main 
  
import "fmt"
  
func main() { 
  
    //Crear canal
    c := make(chan int) 
    select { 
    case <-c: 
    default: 
        fmt.Println("!.. Caso por defecto...!") 
    } 
}

Salida:

!.. Caso por defecto...!

Cuando la declaración select solo tiene canales nil, también se permite el caso por defecto. Como se muestra en el siguiente ejemplo, el canal c es nil, por lo que se ejecuta el caso por defecto. Si el caso por defecto aquí no estuviera disponible, el programa se bloquearía permanentemente, apareciendo un bucle muerto. Si el caso por defecto aquí no estuviera disponible, el programa se bloquearía permanentemente, apareciendo un bucle muerto.

package main
import "fmt"
func main() {
    //Crear canal
    var c chan int
    select {
    case x1 := <-c:
        fmt.Println("Valor: ", x1)
    default:
        fmt.Println("Caso por defecto...!")
    }
}

Salida:

Caso predeterminado...!