Golang
1 chan
channel本质就是数据结构队列
数据是先进先出
是很安全的
无需要加锁。是线程安全的,多个协程操作同一个操作时候,不会发生资源竞争问题
管道也是一个指向的地址。
1.1 管道写
下面是管道的读写,取的实例
package main
import "fmt"
func main(){
var intchan chan int
intchan = make(chan int, 3)
fmt.Println(intchan,&intchan)
}
结果
0xc04205c080 0xc042004028
强调1
管道的容量有限。不可以超过其容量
下面的是如何加数据,并打印长度和容量
func main(){
var intchan chan int
intchan = make(chan int, 3)
fmt.Println(intchan,&intchan)
intchan <- 10
intchan <- 20
fmt.Println(len(intchan),cap(intchan))
}
结果:
0xc04205c080 0xc042004028
2 3
1.2 管道读
强调2
管道的价值在于一边加一边取。
下面的是如何取数据
func main(){
var intchan chan int
intchan = make(chan int, 3)
fmt.Println(intchan,&intchan)
intchan <- 10
intchan <- 20
fmt.Println(len(intchan),cap(intchan))
var num int
num = <- intchan
fmt.Println(num)
}
结果
0xc042072080 0xc04206a018
2 3
10
1.3 管道的有效区间
强调3
如果没有数据了然后还取数据的话会报deadlock错误
func main(){
var intchan chan int
intchan = make(chan int, 3)
fmt.Println(intchan,&intchan)
intchan <- 10
intchan <- 20
fmt.Println(len(intchan),cap(intchan))
var num int
num = <- intchan
fmt.Println(num)
num1 := <- intchan
fmt.Println(len(intchan),num1)
num2:=<-intchan
fmt.Println(num2)
}
1.4 管道的关闭
一旦关闭了就不可以写数据了,只可以读数据
func main(){
intchan := make(chan int,3)
intchan <- 10
intchan <- 20
close(intchan)
intchan<-300
fmt.Println("okok")
}
结果
1.5 管道的遍历
要注意管道的遍历要使用for-range的方法,因为如果是传统的for不好判断循环多少次。
且要提前关闭管道
func main(){
intchan := make(chan int,100)
for i := 1; i < 100;i++{
intchan <- i *2
}
close(intchan)
for v := range intchan{
fmt.Printf("%v",v)
}
}
结果
如果不提前关闭管道的话会报错
2 注意
注意1
上面的实例是map和chan结合使用。每个map又可以有多个key-value
注意2
下面的实例表明了管道和接口的结合引用
接口是一切数据类型的实现类
最后不可以直接输出,会报错
因为cat实现的是接口interface而接口中没有字段。所以编译不通过
所以办法是用类型断言。
type cat struct{
name string
age int
}
func main(){
//interface为所有类别的实现类。
allcat := make(chan interface{},3)
allcat <- 10
allcat <- 20
cat1 := cat{"tom",12}
allcat <- cat1
<-allcat
<-allcat
newcat :=<- allcat
fmt.Printf("%v",newcat)
//编译器觉得cat1是interface,接口中没有字段
//用类型断言
// fmt.Printf("%v",newcat.name)
a := newcat.(cat)
fmt.Printf("%v",a.name)
}