Go Programing
Go Programing
Go Programing Skills
接口型函数
example
1
2
3
4
5
6
7
8
9
// net/http 标准库
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
type HandlerFunc func(ResponseWriter, *Request)
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
使用
- 一个函数类型, 实现了一个接口的方法, 并在该方法中调用自身
- 好处在于既可以将普通函数类型(通过类型转换)作为参数, 可以将结构体作为参数
import <相对路径>相对路径>
- 在go.mod文件中添加声明
- require
<package>v0.0.0 - replace
<package>=> ./<package>
- require
反射
- 反射就是在程序运行时, 可以访问自身结构并且做出修改的一种能力
- go反射中, 都是通过将interface{}转换为Type或者Value类型, 然后通过对Type和Value的操作, 来实现相应的功能
- reflect.TypeOf(any)
- reflect.ValueOf(any)
time.After
example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// example
func doBadthing(done chan bool) {
time.Sleep(time.Second)
done <- true
}
func timeout(f func(chan bool)) error {
done := make(chan bool)
go f(done)
select {
case <-done: // func完成
fmt.Println("done")
return nil
case <-time.After(time.Millisecond): // 启动异步定时器, 超时返回channel
return fmt.Errorf("timeout")
}
}
潜在问题
- 当发生超时的时候, done没有接收者, 导致goroutine阻塞, 没法正常退出
- 避免方式
- channel设置缓冲大小 e.g. done:=make(chan bool, 1)
- 不设置缓冲大小, 而是改用select尝试向done发送信号
- 由done<-true改为select{case done<-true: default: return}
- 当向done发送失败时(此时没有接收者), 走default就退出了
- 这种方式还利于分段检测超时的情况(例如只检测第一段是否超时, 无超时, 后续任务继续执行)
- 避免方式
context
- context可以用来在复杂的情况下并发控制(如控制多个子goroutine, 或者子goroutine又开启了新的goroutine)
- 功能:
- 通知子协程退出(正常退出(context.WithCancel), 超时退出(context.WithTimeout)等)
- 传递必要的参数 (context.WithValue)
This post is licensed under CC BY 4.0 by the author.