Golang - 模块学习

本文详细介绍了Golang中的关键模块,包括context的使用,如Deadline、Done、Err和Value函数;select的机制,如监听IO操作和实现timeout;channel的优缺点及其在并发中的作用;goroutine的概念和优势,如轻量级、快速切换;以及defer的执行顺序和用途,以及panic和recover如何协同工作来控制程序流程。
摘要由CSDN通过智能技术生成

1. context

context是上下文的意思,作为golang的标准包定义了context接口,具有生命周期,具有cancel channel信号的能力,可以用来管理goroutine的生命周期。

 

Context接口有4个实现函数:

Deadline():获取该context的过期时间和是否被设置过期时间

Done():返回一个channel,关闭该channel就代表关闭该context,返回nil代表该context不需要被关闭

Err():context未关闭返回nil;context正常关闭返回canceled;因为过期关闭返回DeadlineExceeded;发生错误返回对应的error

Value():根据指定key从context中取出value,如果没有关联的值返回nil

 

空context:

context.Background():用作初始的context

context.TODO():用作未实现功能的场景中,不清楚作用的context

 

4个非空context:

WithValue():基于现有context派生新的context,同时新context中带有指定的key和value

3个可关闭的context:

WithCancel():根据父context派生新的context,返回一个CancelFunc类型的函数。调用该cancel函数会关闭该context,对应的Done()返回的只读channel也会被关闭。

WithDeadline():根据父context和deadline派生一个新的context,返回值中也有一个CancelFunc函数。当到达过期时间,或者调用CancelFunc函数关闭,或者关闭父context会使生成的context关闭。

WithTimeout():入参中传入父context和一个时间间隔,其余和WithDeadline()类似。

 

2. select

select的每个case都是一个面向channel的IO操作

 

可以用来:

1、监听IO操作

2、实现timeout机制:

// 使用channel和select实现超时机制
func timeout(ch chan interface{}) {
	timeout := make(chan bool, 1)
	go func() {
		time.Sleep(1e9)
		timeout <- true
	}()

	select {
	case x := <-ch:
		fmt.Println(x)
	case <-timeout:
		fmt.Println("It's timeout.")
		return
	}
}

3、配合default检测channel的缓冲区是否已满:

// 使用select的default检测channel buffer是否已满
func isBufferFull() {
	ch := make(chan int, 1)
	ch <- 1

	select {
	case ch <- 2:
		fmt.Println("ch")
	default:
		fmt.Println("ch is full.")
	}
}
func IsBufferFull(ch chan interface{}, x interface{}) {
	select {
	case ch <- x:
		fmt.Printf("%v\n", ch)
	default:
		fmt.Println("It's full.")
	}
}

 

3. channel

优点:带缓冲区的channel可以用来做消息队列,为goroutine之间提供通信;并发安全;可以传递任意类型数据;支持阻塞等待。

缺点:性能不高,用锁实现;容量需要一开始就定好;只能支持本主机上本程序的使用;扩展性差;不能持久化,当进程挂掉时,缓存的消息会丢失。

 

4. goroutine,协程:

协程是在线程之下,线程中多个协程通过调度获取cpu时间片

 

优点:

轻量,创建时所需内存相比进程线程很小

由程序员控制上下文的切换,编程简单,结构清晰,易于理解

并且切换的内容只保存自己的用户态栈和堆内存中,切换的时间快,和同等数量的线程切换相比可以省去很多代价

 

5. defer

在函数返回return执行前,调用defer的操作,可以用来释放资源,做清理工作。

(1)defer表达式确定时,defer修饰的函数的参数也就确定了

func f(){
	i := 0
	defer func(h int){
		fmt.Println(h)
	}(i)
	i++
}

  输出结果是0不是1

(2)函数中有多个defer函数或语句时,defer遵循先进后出原则

(3)函数的返回值被defer修改。保存返回值-》执行defer-》执行return跳转

func fun1() int {	//0
	i:=0
	fmt.Println("(1)",i)
	defer func(){
		i=5
		fmt.Println("(2)",i)
	}()
	return i
}
func fun2() (i int){  	//5
	i=0
	fmt.Println("(1)",i)
	defer func(){
		i=5
		fmt.Println("(2)",i)
	}()
	return  i
}

 

6. panic()和recover()

go的内置函数。

panic是停止程序执行的流程,但是defer还是会执行。

recover是可以捕获前面出现的panic,然后让函数又可以继续正常的执行。可以放到任何位置,但是只有在defer()中的才会起作用。

可以配合panic和recover,来设定返回值。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值