2017-03-11 50 views
0

所以我有点想知道最好的做法是在这里。Golang包和跨包使用变量

我有几个子包的应用程序,一些需要访问记录我在主包,因为我使用自定义记录器,带有颜色和时间戳等

通过注入实现该目标的唯一途径它是这样吗? (假设处理器处于一个子包称为命令)

type Handler struct { 
    logger logging.Logger 
} 

func NewHandler(logger logging.Logger) Handler { 
    return Handler{ 
     logger: logger, 
    } 
} 

handler := command.NewHandler(logger) 

这个问题我有这是测试变得讨厌,因为我有嘲笑的测试记录。 我想过这个问题应记录并让主包对付他们刚刚返回错误,但我想运行一些功能异步像这样

go handler.HandleMessage(msg) 

所以IDK的如何处理异步函数或者错误它甚至有可能。

那么是否有最佳做法来做我想做的事?

回答

1

在这几个想法:

  1. 注入资源(记录)是在我看来,要做到这一点的最好办法。直接引用一个全局变量当然是可能的,但是使你的代码难以改变。
  2. 如果logging.Logger是一个具体类型,那么你可以在nil时使它工作,这样可以在你的测试中跳过初始化。
  3. 你绝对可以在异步调用中处理你的错误。

关于最后一点,你可以使用匿名函数来向主叫站点添加额外的错误处理:

go func() { 
     err := handler.HandleMessage(msg) 
     // err handling/logging here 
}() 

如果你可以有意识传递误差达发起的呼叫,然后我喜欢主叫网站每次都这样做。你需要记住,当你从HandleMessage()返回时你还在单独的goroutine中运行。

+0

谢谢!匿名函数是一个好主意。你能详细解释2吗?我无法通过零。什么是“具体类型”? – gempir

+0

如果logging.Logger是一个接口,那么您需要将它的实现传递给NewHandler以便对其进行调用。另一方面,如果它是一个带有方法Log()的结构体,那么在(log * Logger)Log(msg string)函数中可以检查log == nil,如果是则返回。这意味着一个空的Logger(例如刚刚创建的Handler {})仍然有效 - 您不需要启动它。 –

+0

啊,好吧,这是有道理的。在我的情况logging.Logger是从第三方库的接口,所以我将不得不围绕它写一个包装 – gempir