Golang_chan

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)
}
发布了111 篇原创文章 · 获赞 12 · 访问量 8064

猜你喜欢

转载自blog.csdn.net/qq_43141726/article/details/104426078