defer是go关键字,一般用来清理释放资源,在了解go-kit微服务时,发现了有意思的用法
一般用法--清理释放资源
fd, err := os.Open(filename)
if err != nil {
return
}
defer fd.Close()
使用defer可以避免忘记释放资源。曾经使用lsof -p $pid | grep deleted
帮一个C++老手找出过程序资源句柄忘记Close的问题,go的defer可以有效避免此类问题。
defer的妙用--中间件MiddleWare
package main
import (
"fmt"
"io"
"os"
"strings"
"time"
)
func main() {
var svc stringService
svc = &stringSvc{}
svc = setupLogMiddle(os.Stdout)(svc)
ret := svc.ToUpper("hello")
fmt.Println(ret)
}
// 定义接口
type stringService interface {
ToUpper(string) string
}
type stringSvc struct{}
// 真正的业务service
func (ss *stringSvc) ToUpper(input string) (ret string) {
return strings.ToUpper(input)
}
// 中间件type
type middle func(stringService) stringService
type log struct {
writer io.Writer
stringService
}
// 安装中间件
func setupLogMiddle(writer io.Writer) middle {
return func(ss stringService) stringService {
return &log{writer, ss}
}
}
func (l *log) ToUpper(input string) (ret string) {
// 此处defer执行log中间件
defer func(begin time.Time) {
fmt.Fprintf(l.writer, "method: %s, input: %s, output: %s, took: %v\n",
"ToUpper", input, ret, time.Since(begin))
}(time.Now())
ret = l.stringService.ToUpper(input)
return ret
}
以上是从go-kit看到的,挺有意思,记录下来。