Когда в операторе `select` в Go исполняется ветка `default`?

Ответ

Ветка default в операторе select исполняется тогда, когда ни одна из других веток case не готова к выполнению в момент проверки. Это делает select неблокирующим.

Основное назначение

Использование default позволяет избежать блокировки горутины, если ни один из каналов, перечисленных в case, не готов для отправки или получения данных.

Сценарии использования

  1. Неблокирующее получение из канала:

    ch := make(chan string)
    
    select {
    case msg := <-ch:
        fmt.Println("Получено сообщение:", msg)
    default:
        fmt.Println("Сообщений в канале нет, идем дальше.")
    }
  2. Неблокирующая отправка в канал (например, если он буферизован и полон):

    ch := make(chan int, 1) // Буфер размером 1
    ch <- 1 // Канал заполнен
    
    select {
    case ch <- 2:
        fmt.Println("Успешно отправили 2")
    default:
        fmt.Println("Не удалось отправить 2, канал полон.")
    }
  3. Циклическая проверка состояния в фоновой горутине:

    // Горутина слушает quit канал, но не блокируется, если сигнала нет
    for {
        select {
        case <-quitChan:
            fmt.Println("Получен сигнал завершения.")
            return
        default:
            // Полезная работа, которая выполняется, пока нет сигнала
            time.Sleep(100 * time.Millisecond)
        }
    }

Ключевой вывод

Без default оператор select будет блокироваться до тех пор, пока хотя бы одна из операций case не станет доступной. С default он становится неблокирующим.