go chan简单使用

chan在go中是一个通道有可读可写的chan,也存在只读只写的chan,通过共享内存而实现通信

chan 注意点:
在关闭chan后再关闭chan 会出现panic
关闭chan后可以继续进行取值,取完后可以再取但都是对应类型的0值。
可以通过 v,ok:=<-ch 来判断是否取完了 取完了ok为false
也可以通过for range 来取值

for v:= range ch{
	fmt.Printf("the data is %d",v)
}
for {
	 v,ok:=<-ch 
	 if !ok{
	 fmt.Printf("the data is %d",v)
	 fmt.Println("取完了")
	 }
	fmt.Printf("the data is %d",v)
}

chan需要初始化:

//开辟缓冲区为20的chan
ch1:=make(chan int,20)
//无缓冲区的chan
ch2:=make(chan int)
//只能向chan内写
ch3:=make( chan<-int,20)
ch3 := make(chan<- int, 20)
ch3 <- 10
ch3 <- 20
fmt.Println(len(ch3))
//只能从chan内读
ch4:=make(ch<-chan int,20)

chan 不给缓冲区无法放入值,在某些情况
但是你可以开另外的goroutine来取值,快递原理,不在家储物柜没位置,无法放入快递(放值),快递柜满了,有人来取则可以取值

产生数据并开24个线程消耗数据,并将数据的每一位的和传到主goroutine进行打印
goroutine

package main

import (
	"fmt"
	"math"
	"math/rand"
	"sync"
)

//generate int64 number
func generateRandomNumber(ch chan<- int64) {
	// var i int64
	for {
		ch <- int64(rand.Int63())
	}
}

//get the sum of all digit of input number
// 获取输入数的每一位的和
func GetSum(s int64) int64 {
	strNum := fmt.Sprintf("%d", s)
	lenNum := len(strNum)
	var sumOfAllDigit int64 = 0
	for i := lenNum - 1; i >= 0; i-- {
		temp := s / int64(math.Pow(10, float64(i)))
		fmt.Println(temp)
		s = s % int64(math.Pow(10, float64(i)))
		sumOfAllDigit += temp
	}
	fmt.Println("sum is ", sumOfAllDigit)
	return sumOfAllDigit
}

//24个线程消费生成的数据
func JobChan(wg *sync.WaitGroup, ch chan int64) (sumInfo chan int64) {
	// var chresult chan<- int64
	sumInfo = make(chan int64, 3000)
	for i := 0; i < 24; i++ {
		wg.Add(1)
		go func(ch <-chan int64) {

			for {
				temp := <-ch
				fmt.Println(temp)
				sum := GetSum(temp)
				fmt.Println("temp is ", temp)
				fmt.Println("sum is ", sum)
				sumInfo <- sum
			}
			wg.Done()
		}(ch)

	}
	return
}

func main() {
	 wg := sync.WaitGroup{}
	chOrigin := make(chan int64, 30000)
	// ch1 := make(chan int64, 300)
	go generateRandomNumber(chOrigin)
	chSum := JobChan(&wg, chOrigin)
	for v := range chSum {
		fmt.Println("*&*&*&*&*&***&**", v)
	} 
	// wg.Wait()
	// select {}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Go语言中,`chan := make(chan interface{})`和`chan := make(chan struct{})`这两种通道的定义有一些区别。 1. `chan := make(chan interface{})`:这是一个通用的通道定义,其中的`interface{}`表示通道可以传递任意类型的值。也就是说,我们可以在这个通道中发送和接收任何类型的数据。这种通道的灵活性很高,可以用于传递不同类型的数据。 2. `chan := make(chan struct{})`:这是一个特殊的通道定义,其中的`struct{}`表示通道不传递任何具体的值,只是用于信号传递的作用。空结构体不占用任何内存空间,因此它在作为信号的标志符合时非常节省资源。我们可以通过通道的打开和关闭状态来进行信号的传递。 具体来说,`chan := make(chan interface{})`可以用于传递任意类型的值,例如: ```go ch := make(chan interface{}) go func() { ch <- 42 }() result := <-ch fmt.Println(result) // 输出: 42 ``` 而`chan := make(chan struct{})`通常用于在并发编程中进行信号传递,例如: ```go done := make(chan struct{}) go func() { time.Sleep(2 * time.Second) close(done) }() select { case <-done: fmt.Println("任务完成") case <-time.After(3 * time.Second): fmt.Println("任务超时") } ``` 在这个例子中,我们使用空结构体通道作为一个信号通道,通过`done`通道的关闭来表示任务的完成。通过`select`语句可以等待多个通道的事件,并执行相应的操作。 总结起来,`chan := make(chan interface{})`用于传递任意类型的值,而`chan := make(chan struct{})`用于进行简单的信号传递。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值