这篇说下 go 的一个很重要的技巧,在包装一些链式 API 的时候很实用。
现在用 zerolog 举例,zerolog 是个用法很简单的结构化日志库,性能不错。通过下面的例子感受下用法。
package main
import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func main() {
log.Debug().
Str("Scale", "833 cents").
Float64("Interval", 833.09).
Msg("Fibonacci is everywhere")
}
// Output:
// {"level":"debug","Scale":"833 cents","Interval":833.09,"message":"Fibonacci is everywhere"}
想在 zerolog 的链式 API 加入 ID 函数,还能继承原有的一堆 API,比如.ID("1234") 会在 json 字段里面插入{"ID":"1234"}
package main
import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
func main() {
log.Debug().ID("request id")
Str("Scale", "833 cents").
Float64("Interval", 833.09).
Msg("Fibonacci is everywhere")
}
// Output: {"level":"debug","Scale":"833 cents","Interval":833.09,"message":"Fibonacci is everywhere"}
加上一短代码
func (e *zerolog.Event) ID(id string) *zerolog.Event {
e.Str("ID", id)
return e
}
// 输出
// ./wenti.go:9:6: cannot define new methods on non-local type zerolog.Event
// ./wenti.go:16:13: log.Debug().ID undefined (type *zerolog.Event has no field or method ID)
触发了编译器限制,这条路走不通。
go 是没有语法上的继承的,只有组合。结构提内嵌可以实现方法的继承,在结构提里面写过 sync.Mutex 的都知道。
type Stats struct {
sync.Mutex
}
func (s *Stats) Snapshot() map[string]int {
s.Lock()
defer s.Unlock()
}
使用匿名结构体嵌套,实现方法的复用。
type event struct {
*zerolog.Event
}
func (e *event) ID(id string) *event {
return &event{e.Str("ID", id)}
}
package main
import (
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
)
type Ulog struct {
zerolog.Logger
}
func (u *Ulog) Debug() *event {
return &event{u.Logger.Debug()}
}
func (u *Ulog) Info() *event {
return &event{u.Logger.Info()}
}
func (u *Ulog) Warn() *event {
return &event{u.Logger.Warn()}
}
func (u *Ulog) Error() *event {
return &event{u.Logger.Error()}
}
type event struct {
*zerolog.Event
}
func (e *event) ID(id string) *event {
return &event{e.Str("ID", id)}
}
func main() {
u := Ulog{Logger: log.Logger}
u.Debug().
ID("hello").
Str("Scale", "833 cents").
Float64("Interval", 833.09).
Msg("Fibonacci is everywhere")
}
1
TypeErrorNone 2019-10-31 11:36:48 +08:00
不还是包裹嵌套嘛
|
2
guonaihong OP @TypeErrorNone 看来 ten 兄对 go 也和熟悉。帮看看我的方法可还有提升的地方?
|
3
crclz 2019-10-31 19:05:19 +08:00
很流畅( Fluent )
|
4
reus 2019-11-03 13:20:47 +08:00
这都是入门级别的知识
|
5
guonaihong OP @reus 厉害厉害,可否帮我看下,上面可有能优化的地方。
|