我想知道是否有任何惯用的方法来表示 scoped 语义。所谓scoped,是指:
- scoped mutex(oneliner而不是explicit Lock + delffered Unlock),
- 记录函数(或任何代码块)的入口和出口,
- 测量执行时间。
前两个项目符号的示例代码:
package main
import "log"
import "sync"
func Scoped(m *sync.Mutex) func() {
m.Lock()
return func() {
m.Unlock()
}
}
func Log(what string) func() {
log.Println(what, "started")
return func() {
log.Println(what, "done")
}
}
func main() {
defer Log("testing")()
m := &sync.Mutex{} // obviously mutex should be from other source in real life
defer Scoped(m)()
// use m
}
https://play.golang.org/p/33j-GrBWSq
基本上,我们需要做一个函数调用 * 刚才 *(例如互斥锁),一个调用应该被推迟到defer(例如互斥解锁)。我建议在这里只返回未命名的函数,但它可以很容易地命名(返回带函数字段的结构体)。
只有一个问题:用户可能忘记“呼叫”第一次呼叫的结果。
这段代码是(可以是)惯用的?
4条答案
按热度按时间7gcisfzg1#
将匿名函数作为作用域:
bjp0bcyl2#
你提出的解决方案已经很好了。你返回一个
func
类型的值,你也必须在defer
的末尾调用它。您可以避免这种情况(返回
func
值),但必须有2个函数调用,一个记录 start 事件,另一个记录 end 事件。另一种方法是进行一个函数调用,该函数调用产生延迟的函数的参数值(而不是返回一个函数),该函数使用
defer
语句进行计算,这样它仍然可以保留一行。你也可以在Go Playground上试试:
输出量:
snz8szmq3#
我不相信有一个惯用的方法来做到这一点。我也不知道你为什么要写,写作真的那么糟糕吗
?
3wabscal4#
我认为这个问题与Go语言的习惯性无关,似乎当函数的行为与调用相同时,对代码进行推理通常会更好。为了保持状态,我最好创建一个对象,并将函数定义为该对象上的方法。意思是