go语言中channel的创建和销毁以及匿名函数的使用

channel的创建

go语言中,任意类型前面加上关键字chan即可声明对应类型的通道,创建通道需要使用make,make也用于map 和slice的创建
创建一个通道

/*刚创建的通道是nil*/
var a chan bool
a = make(chan bool)

使用匿名函数创建一个goroutine

go func() {
	for i := 1; i < 10; i++ {
		fmt.Println("子goroutine is running....", i)
	}
	// 往通道中写值
	a <- true
	fmt.Println("结束....")
}()

按照阻塞的方式读取通道中的值

// 读取的操作是注阻塞的
data := <-a
package main

import "fmt"

func main() {
	/*
		通道名 channel
	*/
	/*刚创建的通道是nil*/
	var a chan bool
	fmt.Printf("%T,%v\n", a, a)
	a = make(chan bool)
	// 使用匿名函数创建一个`goroutine`
	go func() {
		for i := 1; i < 10; i++ {
			fmt.Println("子goroutine is running....", i)
		}
		a <- true
		fmt.Println("结束....")
	}()
	fmt.Println("main....over.....")

	// 读取的操作是注阻塞的
	data := <-a
	fmt.Println(data)

	fmt.Println("channel demo")
}

通道关闭

package main

import (
	"fmt"
	"time"
)

func main() {
	/*
		关闭通道:close(ch)
		   子goroutine;写10个数据
		    每写一个,阻塞一次,主goroutine读取一次 解除阻塞
			主goroutine 读取数据
		      每次读取数据,阻塞一次, 子goroutine每次写入一个就解除主阻塞
	*/
	cha1 := make(chan int)
	go sendData1(cha1)
	//读取数据.使用for循环需要自己判断是否通道关闭
	/*	for {
			v, ok := <-cha1
			if !ok {
				fmt.Println("已经读取了所有的数据......", ok)
				break
			}
			fmt.Println("读取的数据....", v)
		}
	*/
	// 使用for range就可以让range自己判断通道啥时候关闭
	// cha1关闭的时候,这里range将停止遍历
	for v := range cha1 {
		fmt.Println("main ..over....", v)
	}
	//单向 只能写数据,不能读数据
	//ch1 := make(chan <- int)
	// 单向只能读不能写数
	//ch2 := make(<- chan int)

	fmt.Println("channel close")
}

func sendData1(cha1 chan int) {
	for i := 0; i < 10; i++ {
		time.Sleep(1000 * time.Millisecond)
		cha1 <- i
	}
	close(cha1)
}

使用通道进行数据发送的小例子
// 1. 创建goroutine1, 向 ch1中发送1,100个数
// 2. 创建goroutine2, 向 ch2中发送, 1,-1000的平方
// 3. main函数中从ch2将值取出

package main

import (
	"fmt"
	"sync"
)

// 1. 创建goroutine1, 向 ch1中发送1,100个数
// 2. 创建goroutine2, 向 ch2中发送, 1,-1000的平方
// 3. main函数中从ch2将值取出

var wg1 sync.WaitGroup

func wg1Fun(ch1 chan int) {
	defer wg1.Done()
	for i := 1; i <= 100; i++ {
		ch1 <- i
	}
	close(ch1)
}

func wg2Fun(ch2 chan int, ch1 chan int) {
	defer wg1.Done()

	for {
		x, ok := <- ch1
		if !ok {
			break
		}
		ch2 <- x * x
	}
	close(ch2)
}


func main() {
	var ch1 = make(chan int, 100)
	var ch2 = make(chan int, 100)
	wg1.Add(2)
	go wg1Fun(ch1)
	go wg2Fun(ch2, ch1)
	wg1.Wait()
	for v := range ch2 {
		fmt.Println("get ch2 is ", v)
	}


}

go语言中,对已经关闭的通道进行取值,能够取到,只不过取到的ok为false

package main

import "fmt"

// 对已经关闭的通道进行取值,能够取到不过ok返回的false

func main() {
	ch1 := make(chan bool, 2)
	ch1 <- true
	ch1 <- true
	// 关闭通道
	close(ch1)

	<- ch1
	<- ch1

	x, ok := <- ch1
	fmt.Println(x, ok)
	x, ok = <- ch1
	fmt.Println(x, ok)
	x, ok = <- ch1
	fmt.Println(x, ok)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Achou.Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值