您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
装饰器(Decorator)是一种常见的编程模式,用于在不修改原始函数或方法的情况下扩展其功能。虽然Go语言没有像Python那样的原生装饰器语法,但通过高阶函数和闭包,我们仍然可以实现类似的装饰器模式。
在Go中,装饰器本质上是一个函数,它接收一个函数作为参数,并返回一个新的函数。这个新函数通常会包装原始函数,在调用前后执行额外的逻辑。
type Decorator func(f func()) func()
func LogDecorator(f func()) func() {
return func() {
fmt.Println("Start executing function")
f()
fmt.Println("Finish executing function")
}
}
func Logger(f func(string)) func(string) {
return func(s string) {
start := time.Now()
fmt.Printf("Calling function with param: %s\n", s)
f(s)
fmt.Printf("Function executed in %v\n", time.Since(start))
}
}
func Greet(name string) {
fmt.Printf("Hello, %s!\n", name)
}
func main() {
decoratedGreet := Logger(Greet)
decoratedGreet("World")
}
func TimeIt(f func()) func() {
return func() {
start := time.Now()
f()
elapsed := time.Since(start)
fmt.Printf("Function took %s\n", elapsed)
}
}
func HeavyComputation() {
time.Sleep(1 * time.Second)
}
func main() {
timedHeavyComputation := TimeIt(HeavyComputation)
timedHeavyComputation()
}
func ErrorHandler(f func() error) func() error {
return func() error {
err := f()
if err != nil {
fmt.Printf("Error occurred: %v\n", err)
}
return err
}
}
func MightFail() error {
if rand.Intn(2) == 0 {
return errors.New("random error")
}
return nil
}
func main() {
safeMightFail := ErrorHandler(MightFail)
safeMightFail()
}
对于有多个参数的函数,我们可以使用可变参数或定义特定签名的装饰器:
func GenericLogger(f interface{}) interface{} {
switch fn := f.(type) {
case func(int):
return func(n int) {
fmt.Printf("Calling with int: %d\n", n)
fn(n)
}
case func(string):
return func(s string) {
fmt.Printf("Calling with string: %s\n", s)
fn(s)
}
default:
panic("unsupported function type")
}
}
我们可以将多个装饰器组合起来,形成装饰器链:
func Compose(decorators ...Decorator) Decorator {
return func(f func()) func() {
for i := len(decorators) - 1; i >= 0; i-- {
f = decorators[i](f)
}
return f
}
}
func main() {
composed := Compose(TimeIt, LogDecorator)(HeavyComputation)
composed()
}
装饰器也可以应用于结构体方法:
type Service struct{}
func (s *Service) Process() {
fmt.Println("Processing...")
}
func MethodLogger(f func()) func() {
return func() {
fmt.Println("Before method call")
f()
fmt.Println("After method call")
}
}
func main() {
s := &Service{}
decoratedProcess := MethodLogger(s.Process)
decoratedProcess()
}
虽然Go没有内置的装饰器语法,但通过高阶函数和闭包,我们仍然可以实现强大的装饰器模式。装饰器在日志记录、性能监控、错误处理等横切关注点上特别有用。合理使用装饰器可以帮助我们保持代码的DRY原则,同时提高代码的可维护性。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。