В чем разница между switch и select в Go?
есть ли разница между switch
и select
в Go,
помимо того, что один принимает аргумент, а другой нет?
3 ответов
A select
используется только с каналами. пример
A switch
использовано с конкретными типами. пример
A select
будет выбирать несколько допустимых параметров наугад, в то время какswitch
будет идти в последовательности(и потребует fallthrough, чтобы соответствовать нескольким.)
обратите внимание, что коммутатор также может переходить по типам интерфейсов при использовании с ключевым словом .(type)
var a interface{}
a = 5
switch a.(type) {
case int:
fmt.Println("an int.")
case int32:
fmt.Println("an int32.")
}
// in this case it will print "an int."
переключатель используется для принятия решения на основе значения переменной любого типа. Читать этой для получения более подробной информации:
переключатель Go более общий, чем C. Выражения не должны быть константами или даже целыми числами, случаи вычисляются сверху вниз до тех пор, пока не будет найдено совпадение, и если переключатель не имеет выражения, он включает true. Поэтому возможно-и идиоматично-написать цепочку "если-еще-если-еще" в качестве переключателя.
Пример Использования: ( Go Playground)
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Print("Go runs on ")
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
// freebsd, openbsd,
// plan9, windows...
fmt.Printf("%s.", os)
}
}
на выберите оператор позволяет goroutine ждать нескольких операций связи.
a select блокирует до тех пор, пока один из его случаев не сможет работать, затем он выполняет этот случай. Он выбирает один наугад, если несколько готовы. Вот один пример: ( Go Playground)
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(100 * time.Millisecond)
boom := time.After(500 * time.Millisecond)
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
return
default:
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
}
оператор "select" выбирает, какой из набора возможных отправки или приемные операции будут продолжаться. Он похож на " переключатель" заявление, но со всеми случаями, относящимися к сообщению оперативный.
операторы"Switch" обеспечивают многоходовое выполнение. Выражение или тип спецификатор сравнивается с" случаями " внутри "переключатель" для определения какую ветку выполнять. Существует две формы: Expression switches и переключатели типа. В коммутаторе выражений случаи содержат выражения которые сравниваются со значением выражения switch. В тип переключатель, случаи содержат типы, которые сравниваются с тип специально аннотированного выражения switch. Выражение переключателя оценивается только один раз в операторе switch.
Да, есть много различий:
-
select
работает только на событиях канала (прием, закрытие или ожидание), но вы можете использоватьswitch
просто для сравнения данных канал Какcase <-ch == 1:
-
switch
работает детерминированным образом, как несколькоif
илиif else
утверждение, ноselect
выбираетcase
недетерминированным способом: вы не можете сказать, какой случай запускается первым вselect
- вы не можете использовать
fallthrough
наselect
- на
switch
спецификатор выражения или типа по сравнению сcases
внутриswitch
чтобы определить, какую ветку выполнить. -
switch
не блокирует себя, ноselect
блокирует базовый goroutine, если вы не используетеdefault
-
switch
имеет две формы: переключатели выражений и переключатели типов - в блокировании
select
(безdefault
) нет использования процессора (goroutine sleep) - в отличие от
select
вы не можете использоватьcase <-ch:
внутриswitch
.
рабочая пример кода:
package main
import "fmt"
func main() {
ch := make(chan int, 4)
ch <- 1
ch <- 2
ch <- 3
ch <- 4
close(ch)
switch {
//case <-ch: // invalid case <-ch in switch (mismatched types int and bool)
case <-ch == 1:
fmt.Println("switch1")
fallthrough
case <-ch == 2:
fmt.Println("switch2")
}
select {
case d := <-ch:
fmt.Println("select1 d=", d)
case d := <-ch:
fmt.Println("select2 d=", d)
}
}
выход:
switch1
switch2
select2 d= 2
вывод еще раз:
switch1
switch2
select1 d= 2