最近在学习Go语言,我在这里把遇到的一些坑还有难点记录下。
Map中的坑
map没法直接用struct
下面的代码会报错
1
2
3
4
5
6
7
8
9
10
11
12
|
package main
import "fmt"
var m = map[string]struct{x, y int} {
"foo": {2, 3},
}
func main() {
m["foo"].x = 4 // cannot assign to m["foo"].x
fmt.Println(m)
}
|
解决的办法是用指针
1
2
3
4
5
6
7
8
9
10
11
12
|
package main
import “fmt”
var m = map[string]*struct{x, y int} {
“foo”: {2, 3},
}
func main() {
m[“foo”].x = 4
fmt.Println(m[“foo”].x)
}
|
Channel
定义
1
2
|
messages := make(chan string, 2)
done := make(chan bool)
|
###发送接收数据
1
2
|
ch <- v // 发送v到channel ch.
v := <-ch // 从ch中接收数据,并赋值给v
|
默认情况的channel是阻塞式的,可以把channel理解为水管,阻塞式channel是一根小水管,一有东西进来,他就会堵住,除非channel里面的东西被取出。
也可以有非阻塞的channel,这样的channel可以存放多个数据,只要在make的时候用第二个参数执行channel的长度就可以了。非阻塞式channel只有当写入数据达到channel长度的时候才会阻塞。
用range遍历非阻塞channel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package main
import (
"fmt"
)
func fibonacci(n int, c chan int) {
x, y := 1, 1
for i := 0; i < n; i++ {
c <- x
x, y = y, x + y
}
close(c)
}
func main() {
c := make(chan int, 10)
go fibonacci(cap(c), c)
for i := range c {
fmt.Println(i)
}
}
|
语法跟一般的for range非常类似。但是要注意你很可能需要用close关闭channel,否则会一直循环下去。
判断channel是否关闭
从channel中读取数据的时候,指定两个变量,第一个变量存放channel中的数据,第二个变量用来表示channel是否关闭
select
我们上面介绍的都是只有一个channel的情况,那么如果存在多个channel的时候,我们该如何操作呢,Go里面提供了一个关键字select,通过select可以监听channel上的数据流动。
select默认是阻塞的,只有当监听的channel中有发送或接收可以进行时才会运行,当多个channel都准备好的时候,select是随机的选择一个执行的。
select也可以是非阻塞的
如果在select里面提供default选项,那么如果所有其他选项的channel都没数据的时候,会执行default选项,也就不会阻塞了。