dousui6488 2016-12-02 05:50 采纳率: 100%
浏览 33
已采纳

从内部函数安全引用外部函数中的值?

I am moving to Go from Node.js and I am concerned whether a construct that I would use in Node is safe to do in Go and whether there is a more idiomatic way to accomplish the same thing. I am using the Echo framework and want to set a route specific struct that will be available within the context object. I could generate the struct for every call within middleware, but it's expensive to do so. Instead, I set the struct once in an outer func that then returns an inner func that refers to the struct in the outer func. My hope is that I then only incur the generation cost once and then have the correct struct associated with my route for every call.

e.POST(path, POST.GenericPostHandler, func(next echo.HandlerFunc)  echo.HandlerFunc {
    operation := getOperationMap(path)
    return func(c echo.Context) error {
        c.Set("op", operation)
        return next(c)
    }
})

Are there any concerns with this code? Will it cause problems with GC? Is there a more efficient way to accomplish the same thing? I assume a copy of the struct is made every time the middleware is called.

  • 写回答

2条回答 默认 最新

  • douchu2823 2016-12-02 06:24
    关注

    If operationMap never changes after initialization, You can declare operationMap as a singleton instance like following:

    package main
    
    import (
        "fmt"
        "sync"
    )
    
    var (
        operationMapInst map[string]string // I don't know the exact type of map, so you should change the type.
        operationMapOnce sync.Once
    )
    
    func getOperationMap() map[string]string {
        // operationMapOnce.Do() runs only once
        // when the first time getOperationMap() is called.
        operationMapOnce.Do(func() {
            // Initialize operationMapInst.
            operationMapInst = map[string]string{"/": "root", "/ver": "version"}
            fmt.Println("operaionMap has initialized!")
        })
    
        return operationMapInst
    }
    
    func main() {
        // The initialization logic runs only once.
        // Because getOperationMap() returns map,
        // syntax for the value for a path should be getOperationMap()[path],
        // not getOperationMap(path).
        rootOp, ok := getOperationMap()["/"]
        fmt.Println(rootOp, ok)
    
        // repetition
        rootOp, ok = getOperationMap()["/"]
        fmt.Println(rootOp, ok)
        verOp, ok := getOperationMap()["/ver"]
        fmt.Println(verOp, ok)
        verOp, ok = getOperationMap()["/ver"]
        fmt.Println(verOp, ok)
    }
    

    You can run this code here.

    I recommend http://marcio.io/2015/07/singleton-pattern-in-go/ for understanding singleton pattern in Go.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么