РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
1475 of 1593 menu

Функция reflect.Select

Функция reflect.Select выполняет выбор из набора каналов, аналогично оператору select в Go, но в рефлексии. Она принимает слайс из структуры reflect.SelectCase, которая описывает каждую операцию над каналом. Функция возвращает индекс выбранного случая, значение, полученное из канала (если это операция приема), и флаг, указывающий, было ли значение получено успешно. Эта функция является ключевым инструментом для динамической работы с каналами, когда структура операций выбора заранее неизвестна.

Синтаксис

reflect.Select(cases []reflect.SelectCase) (chosen int, recv reflect.Value, recvOK bool)

Структура reflect.SelectCase

Структура reflect.SelectCase описывает один случай в операторе выбора. Она содержит три поля:

  • Dir - направление операции: reflect.SelectSend (отправка), reflect.SelectRecv (прием) или reflect.SelectDefault (по умолчанию);
  • Chan - значение типа reflect.Value, представляющее канал;
  • Send - значение для отправки, если операция отправки.

Пример 1: Блокирующий выбор

Давайте создадим два канала и выполним блокирующий выбор между ними:

package main import ( "fmt" "reflect" "time" ) func main() { ch1 := make(chan string) ch2 := make(chan string) go func() { time.Sleep(100 * time.Millisecond) ch1 <- "from channel 1" }() go func() { time.Sleep(50 * time.Millisecond) ch2 <- "from channel 2" }() cases := []reflect.SelectCase{ { Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch1), }, { Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch2), }, } chosen, recv, recvOK := reflect.Select(cases) fmt.Printf("chosen: %d, recv: %s, recvOK: %t", chosen, recv.String(), recvOK) }

Результат выполнения кода:

"chosen: 1, recv: from channel 2, recvOK: true"

Пример 2: Отправка данных в канал

Давайте выполним операцию отправки данных в канал:

package main import ( "fmt" "reflect" ) func main() { ch := make(chan int, 1) cases := []reflect.SelectCase{ { Dir: reflect.SelectSend, Chan: reflect.ValueOf(ch), Send: reflect.ValueOf(12345), }, } chosen, recv, recvOK := reflect.Select(cases) fmt.Printf("chosen: %d, recv: %s, recvOK: %t", chosen, recv.String(), recvOK) }

Результат выполнения кода:

"chosen: 0, recv: <invalid Value>, recvOK: false"

Пример 3: Неблокирующий выбор с default

Давайте используем операцию по умолчанию для неблокирующего выбора:

package main import ( "fmt" "reflect" ) func main() { ch := make(chan int) cases := []reflect.SelectCase{ { Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ch), }, { Dir: reflect.SelectDefault, }, } chosen, recv, recvOK := reflect.Select(cases) fmt.Printf("chosen: %d, recv: %s, recvOK: %t", chosen, recv.String(), recvOK) }

Результат выполнения кода:

"chosen: 1, recv: <invalid Value>, recvOK: false"

Смотрите также

  • функцию reflect.MakeChan,
    которая создает канал в рефлексии
  • функцию reflect.ValueOf,
    которая возвращает значение как объект рефлексии
  • функцию reflect.TypeOf,
    которая возвращает тип значения в рефлексии
  • функцию reflect.DeepEqual,
    которая выполняет глубокое сравнение значений
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить