Search code examples
goidiomsdefer-keywordlexical-cleanup

Is there idiomatic scoped semantics in golang?


I wonder if there is any idiomatic way to represent scoped semantics. By scoped I mean things like:

  • scoped mutex (oneliner instead of explicit Lock + deffered Unlock),
  • logging function (or any code block) entrance and exit,
  • measuring execution time.

Example code for first two bullets:

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

Basically we need to make one function call just now (eg mutex lock), and one call should be postponed to defer (eg mutex unlock). I propose just returning unnamed function here, but it can be easily named (return struct with function field).

There is only one problem: user can forget to 'call' result of first call.

This code is (can be) idiomatic?


Solution

  • I do not believe there is an idiomatic way to do this. I'm not sure why you'd want to either, is it really so bad to write

    m.Lock()
    defer m.Unlock()
    

    ?