当前位置:   article > 正文

Go 语言 channel通道的基础知识_go语言对nil的channel

go语言对nil的channel

Go 语言 channel通道的基础知识

通道(channel)就是一个管道,可以想象成Go 协程之间通信的管道,他是一种队列的数据结构,遵循先进先出的规则

通道的声明

每一个通道只能传递一种数据结构的数据,在我们声明的时候,就要指定管道的类型,chan Type 表示Type类型的通道,通道的零值为nil

var channel_name chan channel_type

func channel() {
	//声明了一个类型为string的通道,值为nil
	var channel chan string
    channel =make(chan string)
	fmt.Println(channel)
    
    //简单的声明方式
    ch :=make(chan string)
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
管道初始化以及使用

声明完通道之后,其值为nil,我们不能直接使用,必须先使用make函数对通道进行初始化操作

package main

import (
	"fmt"
	"time"
)

func channel() {
	//声明了一个类型为string的通道,值为nil
	var channel chan string
	fmt.Println(channel)
}

func PrintChan(c chan string) {
	c <- "第七魂技 - 武魂真身"
}
func ChanTest() {
	/**
	发送数据  channel_name <- data
	接收数据  value :=<-channel_name
	*/
	//创建一个通道
	ch := make(chan string)
	fmt.Println("第一魂技。。。")
	//开启协程
	go PrintChan(ch)
	//从通道中获取数据
	res := <-ch
	fmt.Println(res)
	fmt.Println("第九魂技。。。")
	//关闭通道
	close(ch)
	_, ok := <-ch
	//检查通道是否关闭
	fmt.Println(ok)

	/**
	无缓冲通道
	c :=make(chan int)
	c :=make(chan int,0)
	缓冲通道
	 c :=make(chan int ,3)//数值
	*/
	c := make(chan int)
	go func() {
		fmt.Println("send 1")
		c <- 1
	}()

	go func() {
		n := <-c
		fmt.Println("receive", n)
	}()
	time.Sleep(1 * time.Second)

}

/**
只读通道  <-than
只写通道 chan <-
*/
type Sender = chan<- string
type Receiver = <-chan string

func ChanTest01() {
	//创建一个双向通道
	ch := make(chan string)
	go func() {
		var sender Sender = ch
		fmt.Println("即将学习。。。")
		sender <- "第二魂技-床绕"
	}()

	go func() {
		var receiver Receiver = ch
		message := <-receiver
		fmt.Println("开始学习:", message)
	}()

	time.Sleep(1 * time.Second)
}

func RangeChan() {
	//遍历通道 for range
	var channel = make(chan int, 5)
	go LoopPrint(channel)
	for v := range channel {
		fmt.Println(v)
	}
	channel1 := make(chan bool, 1)
	var x int
	for i := 0; i < 1000; i++ {
		go increment(channel1, &x)
	}

	time.Sleep(1 * time.Second)
	fmt.Println("x=", x)
}
func LoopPrint(c chan int) {
	for i := 0; i < 10; i++ {
		c <- i
	}
	close(c)
}
func increment(ch chan bool, x *int) {
	ch <- true
	//不是原子操作,避免多协程进行操作;使用容量为1的通道,达到锁的效果
	*x = *x + 1
	<-ch
}

func funcReceiver(c chan bool) {
	fmt.Println(<-c)
}
func main() {
	RangeChan()

	ch := make(chan bool)
	//1.开启一个协程,再往管道写入数据,这样就不会产生死锁  go funcReceiver(ch)
	//2. 把无缓冲通道改为有缓冲通道  ch := make(chan bool, 1)
	//go funcReceiver(ch)
	//往通道里写数据
	ch <- true
	//通道里读数据 ---看上去没啥问题,其实会产生死锁  fatal error: all goroutines are asleep - deadlock!
	fmt.Println(<-ch)
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号