golang 中是否有惯用的作用域语义?

我想知道是否有任何惯用的方式来表示范围语义。通过作用域,我的意思是这样的:


作用域互斥锁(oneliner 而不是显式锁定 + 延迟解锁),

记录函数(或任何代码块)的入口和出口,

测量执行时间。

前两个项目符号的示例代码:


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


基本上我们刚刚需要进行一次函数调用(例如互斥锁),并且应该将一次调用推迟到延迟(例如互斥解锁)。我建议在这里只返回未命名的函数,但它可以很容易地命名(返回带有函数字段的结构)。


只有一个问题:用户可能会忘记“呼叫”第一次呼叫的结果。


这段代码是(可以)惯用的吗?


慕桂英4014372
浏览 165回答 3
3回答

幕布斯7119047

以匿名函数为作用域:func() {    Entrance()    defer Exit()    // anything you want to do in this scope}()

慕尼黑8549860

您提出的解决方案已经很好了。您返回一个func类型的值,您还必须在defer.您可以避免这种情况(返回一个func值),但必须有 2 个函数调用,一个记录开始事件,另一个记录结束事件。另一种方法是进行一个函数调用,该函数调用会产生延迟(而不是返回一个函数)的函数的参数值,该参数值是用defer语句评估的,这样它仍然可以保留一行。您也可以在Go Playground上尝试:func start(s string) string {    fmt.Println("Started", s)    return s}func end(name string) {    fmt.Println("Ended", name)}func main() {    defer end(start("main"))    fmt.Println("Doing main's work...")}输出:Started mainDoing main's work...Ended main

阿晨1998

我不相信有一种惯用的方法可以做到这一点。我不知道你为什么想要,写起来真的很糟糕吗m.Lock()defer m.Unlock()?
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go