<p>What is the best way to have a global config store accessible by any functions in the same package? Reading and parsing a json config isn't the issue here. The config is usually loaded and read from the main function but if I want to have any functions to read from this config without having the main function to pass down the config. </p>
<p>I've thought of having a global variable, but not sure if its the best way. In C/C++, I usually use a singleton. In other languages like PHP, I employ the dependency injection pattern.</p>
<hr/>**评论:**<br/><br/>tjholowaychuk: <pre><p>IMO what you're trying to do could easily be considered an anti-pattern. I would personally either:</p>
<ul>
<li>pass config to some struct and reference it via the field(s)</li>
<li>pass as little as possible to each function, don't assume entire config structs etc</li>
</ul>
<p>Usually going with the least amount of indirection possible leads to nicer implementations, but it sort of depends on the use-case a bit – though I'd certainly stay away from global config.</p>
<p>I try to do all "bootstrapping" of config in the 'main' package, everything else simply becomes a package as if it were going to be open-sourced and used as such, rather than strictly designed as an application or CLI. </p></pre>peterbourgon: <pre><blockquote>
<p>pass as little as possible to each function, don't assume entire config structs etc</p>
</blockquote>
<p>+1 to this. In general, the concept of a "config" should be bounded to the scope of your <code>func main</code>. Each of your components should take precisely the configuration they require as parameters, either </p>
<ul>
<li>directly — <code>func NewFoo(a int, b string)</code>, </li>
<li>through <a href="http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis">the functional options idiom</a>, or</li>
<li>through a config struct — <code>func NewFoo(opts FooOptions)</code>),</li>
</ul>
<p>in order of preference. There are probably circumstances where a global config struct is appropriate, but they're exceptional.</p></pre>anoobisus: <pre><p>This also, you know, makes it possible to test shit in a reasonable way too</p></pre>singron: <pre><p>I like to do something like this:</p>
<pre><code>var Config struct {
homedir string
maxRefreshes int
http struct {
addr string
basePath string
}
}
</code></pre>
<p>You can configure these however you want, but usually I have an init() function that uses the flag package.</p>
<pre><code>func init() {
flag.StringVar(&Config.homedir, "homedir", ".", "directory to use for stuff")
// etc.
}
func main() {
flag.Parse()
http.ListenAndServe(Config.http.addr, ...) // or whatever
}
</code></pre>
<p>There are a couple packages that will do this kind of thing a little more easily with struct tags and reflection, but it's essentially the same thing.</p></pre>ApatheticGodzilla: <pre><p>I do something similar, using environment variables.</p></pre>gureggu: <pre><p>I pass around a <code>x/net/context.Context</code> everywhere and shove the config inside of that. </p></pre>joeshaw: <pre><p>+1 to this. I recently moved a lot of globalish things here (config, <code>database.DB</code>, statsd client, S3 client, etc.) and the functions are much cleaner as a result. Because contexts are loosely coupled, it's still easy to construct contexts with only the things you need for tests.</p></pre>lhxtx: <pre><p>I just pass around a config struct. </p></pre>lethalman: <pre><p>Not have a global config. Pass it everywhere in any function. That makes your software easier to run, to embed, to reuse and to test.</p></pre>jerf: <pre><p>I use an <a href="http://www.jerf.org/iri/post/2929" rel="nofollow">environment object</a>, which turns out to work out pretty well because as you refine your system into objects that are having methods run on them, rather than passing them "everywhere" you often end up just passing them to "a few places", then they end up available everywhere via the sort of natural struct embedding you'd be doing anyhow. It's much more convenient than it sounds at first. Still harder than global variables, but much safer and more testable.</p></pre>axaxs: <pre><p>If it's a shared, static config, just use a global.</p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传