- 通道中没有数据, 接收数据会阻塞, 可以用第二个参数解决
- 发送超过通道容量会阻塞
- select 没有 default 会阻塞, 有 default 不会阻塞
- select 语句最多只会有一个 case 命中
- 通道关闭了, 可以收数据, 不可以发数据
上代码, 自己品:
package main
import "fmt"
func main() {
ch := make(chan int) // 无缓存通道
// 阻塞在发送语句
ch <- 2 // fatal error: all goroutines are asleep - deadlock!
ele := <-ch
fmt.Println(ele)
}
package main
import "fmt"
func main() {
ch := make(chan int) // 无缓存通道
go func() {
ch <- 2
}()
ele := <-ch
fmt.Println(ele) // 2
}
package main
import "fmt"
func main() {
ch := make(chan int) // 无缓存通道
// 阻塞在接收语句
ele := <-ch // fatal error: all goroutines are asleep - deadlock!
fmt.Println(ele)
go func() {
ch <- 2
}()
}
package main
import "fmt"
func main() {
ch := make(chan int) // 无缓存通道
i := 2
go func() {
// 通道内的是 i 的副本
ch <- i
i = 1
}()
ele := <-ch
fmt.Println(ele) // 2
}
package main
import "fmt"
func main() {
ch := make(chan *int) // 无缓存通道
i := 2
j := &i
fmt.Printf("j (%v --> %v) = %d\n", &j, j, *j) // j (0xc000122018 --> 0xc000128008) = 2
go func() {
// 通道内的是指针 j 的副本
ch <- j
*j = 1
}()
ele := <-ch
fmt.Printf("ele (%v --> %v) = %d\n", &ele, ele, *ele) // ele (0xc000122028 --> 0xc000128008) = 1
}
package main
import "fmt"
func main() {
// FIFO
ch := make(chan int, 2) // 有缓存通道
ch <- 2
ch <- 1
ele := <-ch
fmt.Println(ele) // 2
ele = <-ch
fmt.Println(ele) // 1
ch <- 3
ele = <-ch
fmt.Println(ele) // 3
ch <- 4
}
package main
import "fmt"
func main() {
// FIFO
ch := make(chan int, 2) // 有缓存通道
ele := <-ch // fatal error: all goroutines are asleep - deadlock!
fmt.Println(ele)
}
package main
import "fmt"
func main() {
// FIFO
ch := make(chan int, 2) // 有缓存通道
ch <- 2
ch <- 1
ch <- 3 // fatal error: all goroutines are asleep - deadlock!
ele := <-ch
fmt.Println(ele)
}
package main
import "fmt"
func main() {
ch1 := make(chan string, 1)
ch1 <- "chan 1"
select {
case ele := <-ch1:
fmt.Println(ele) // chan 1
}
}
package main
import "fmt"
func main() {
ch1 := make(chan string, 1)
select {
// 阻塞在接收语句
case ele := <-ch1: // fatal error: all goroutines are asleep - deadlock!
fmt.Println(ele)
}
}
package main
import "fmt"
func main() {
ch1 := make(chan string, 1)
ch1 <- "chan 1"
select {
case ele := <-ch1:
fmt.Println(ele) // chan 1
default:
fmt.Println("Default")
}
}
package main
import "fmt"
func main() {
ch1 := make(chan string, 1)
select {
case ele := <-ch1:
fmt.Println(ele)
default:
fmt.Println("Default") // Default
}
}
package main
import "fmt"
func main() {
ch1 := make(chan string, 1)
ch2 := make(chan string, 1)
ch1 <- "chan 1"
ch2 <- "chan 2"
select {
case ele := <-ch1:
fmt.Println(ele) // chan 1
case ele := <-ch2:
fmt.Println(ele)
}
}
package main
import "fmt"
func main() {
ch1 := make(chan string, 1)
ch2 := make(chan string, 1)
ch1 <- "chan 1"
ch2 <- "chan 2"
select {
case ele := <-ch2:
fmt.Println(ele) // chan 2
case ele := <-ch1:
fmt.Println(ele)
}
}
package main
import "fmt"
func main() {
ch1 := make(chan string, 1)
ch2 := make(chan string, 1)
select { // fatal error: all goroutines are asleep - deadlock!
case ele := <-ch2:
fmt.Println(ele) // chan 2
case ele := <-ch1:
fmt.Println(ele)
}
}
package main
import "fmt"
func send(ch chan<- string) {
ch <- "send"
// 不允许接收 ch 中的数据
//<-ch // Invalid operation: <-ch (receive from send-only type chan<- string)
}
func receive() <-chan string {
ch := make(chan string, 1)
ch <- "receive"
return ch
}
func print(ch <-chan string) {
fmt.Printf("print: %s\n", <-ch)
}
// 单向通道可以起到约束的作用
func main() {
ch := make(chan string, 1)
send(ch)
print(ch) // print: send
ch1 := receive()
ele := <-ch1
fmt.Println(ele) // receive
// 不允许向 ch1 中发送数据
//ch1 <- "other" // Invalid operation: ch1 <- "other" (send to receive-only type <-chan string)
}
package main
func main() {
ch := make(chan int, 1)
close(ch)
ch <- 2 // panic: send on closed channel
}
package main
import "fmt"
func main() {
ch := make(chan int, 1)
close(ch)
ele := <-ch
fmt.Println(ele) // 0
}
package main
import "fmt"
func main() {
ch := make(chan int, 1)
close(ch)
ele, ok := <-ch
fmt.Println(ele, ok) // 0 false
}
package main
import "fmt"
func main() {
ch := make(chan int, 1)
//close(ch)
ele, ok := <-ch // fatal error: all goroutines are asleep - deadlock!
fmt.Println(ele, ok)
}
package main
import "fmt"
func main() {
ch := make(chan int, 1)
ch <- 2
close(ch)
ele, ok := <-ch
fmt.Println(ele, ok) // 2 true
ele, ok = <-ch
fmt.Println(ele, ok) // 0 false
}