Learn Go channel

 

学习Go channels 的记录

最近在YouTube上看一个GO 的学习视频。记录下学习过程的知识点。 链接在这里:

Learn Go Programming - Golang Tutorial for Beginners

因为太长了,YouTube不能自动生成字幕。啃的生肉,有理解不恰当地方的欢迎指正

废话不多说直接上代码:

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
package main

import (
	"fmt"
	"time"
)

const (
	logInfo   = "INFO"
	logWaring = "WARNING"
	logError  = "ERROR"
)

type logEntry struct {
	time      time.Time
	serverity string
	message   string
}

var logCh = make(chan logEntry, 50)
var doneCh = make(chan struct{}) 
// 信令通道。使用struct{} 作为信令通道是消耗最小的。不会请求额外的内存资源

func main() {
	go logger()
	logCh <- logEntry{time.Now(), logInfo, "App is starting"}

	logCh <- logEntry{time.Now(), logInfo, "App is shuting down"}
	time.Sleep(100 * time.Millisecond)
	doneCh <- struct{}{} // use this is no memory cost
}

func logger() {
	for {
		select { // 阻塞 ,直到channel 中有信号传入。开始进行匹配
		case entry := <-logCh:
			fmt.Printf("%v - [%v]%v\n", entry.time.Format("2006-01-02 15:04:05"), entry.serverity, entry.message)
		case <-doneCh:
        // 从doneCh 中取到信号,说明main goroutine 发出了结束信息。 break挑出循环,结束程序
			break
        default: 
        // 如果不加default 部分,程序会一直阻塞直到有(信号、信息)传入channel 中。
        // 加了default 后,在channel 中无数据时,将会执行default部分。
            //something 
		}
	}
}

两种从channel中获取数据的方法:

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
package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

func main() {
	ch := make(chan int)
	wg.Add(2)
	go func(ch <-chan int) { // write only channel

        // 第一种 使用range 获取 类似slice 或 map 行为
		// for i := range ch {
		// 	fmt.Println(i)
		// }

        // 第二种 适合多channel 获取不同channel 的数据 , 与上面例子中使用select 获取channel数据类似
		for {
			if i, ok := <-ch; ok {
				fmt.Println(i)
			} else {
				break
			}
		}
		wg.Done()
	}(ch)
	go func(ch chan<- int) { // read only channel
		ch <- 42
		ch <- 901
		close(ch)
		wg.Done()
	}(ch)
	wg.Wait()
}

– 返回顶部 –