英文:
managing env variables in Go libraries
问题
我正在使用Go语言编写一个库。有几个可配置的值,我想了解一些设置这些值的好方法。我考虑了以下几个选项:
- 使用os.Getenv()函数获取环境变量的值,无论在哪里使用它们。缺点是多次读取同一个环境变量。
- 创建一个配置文件,读取所有的配置变量,并将配置结构体传递给需要使用的地方。我不打算在多个地方传递这样的结构体。有些文件在启动时需要一个静态值。
- 使用init()函数;据我所知,这不被推荐,至少不推荐多次使用init()函数。
还有没有更简单、更清晰的方法推荐?
英文:
I am writing a library in Go. There are several configurable values and I am looking to understand some good ways to set these values. I have considered following options:
- use os.Getenv() to get values of env variables wherever they are to be used. Drawback is reading same env variable multiple times.
- Create a config file, read all config variables, and pass the config struct around. I do not intend to pass such struct around in multiple places. There are files which need a static value determined at startup.
- Use init() function; afaik this is not recommended, at least multiple init are not recommended.
Any more recommendations on a simpler and cleaner approach?
答案1
得分: 1
从配置文件或环境中读取设置应该在启动时完成。如果我理解正确,你的问题是关于如何将这些值注入到其他包中。
以下是一些想法。
- 一个包含所有设置的全局配置包。在启动时读取设置,然后在全局范围内使用。优点:所有设置都可以在任何地方使用。缺点:设置是可变的,考虑通过添加函数并不导出设置对象来使其只读。
- 在启动时读取设置后,将其注入到每个包中。需要设置的包可以有一个公共的
Init(...)
函数,接受所有必要的设置。不要使用init()
。优点:没有大型的配置结构,只有必要的设置。缺点:到处都是全局变量,很容易变得混乱,可能会忘记调用Init()
等。 - 要求设置:为了避免上述涉及全局变量的混乱,只需在使用设置的所有代码中要求设置:对于函数,将设置作为参数接受。如果有带有方法的结构体,更好:将设置作为需要定义的结构体字段。如果有构造函数,让构造函数接受设置。优点:没有全局变量,对设置的依赖清晰明确。缺点:可能不明显哪些值是应用程序设置,直到追溯其来源。
第3种方法是我最喜欢的方法,因为它可以更清楚地了解设置的来源和使用方式。
英文:
Reading settings from config files or the environment should be done at startup. If I understand correctly, your question is about how these values should be injected into other packages.
Here is a few ideas.
- A global config package that contains all settings. The settings are read on startup and are then globally available here. Pro: all settings available, everywhere. Con: Settings are mutable, consider making them read only by adding functions and not exporting the settings object.
- After reading in the settings on startup, inject them into each package. A package that requires a setting can have a public
Init(...)
function that accepts all necessary settings. Don't useinit()
. Pro: no big config structs, only necessary settings. Con: globals all over the place, can become messy very fast, you can forget to callInit()
, etc. - Require settings: To avoid the chaos involving globals described above, just require settings in all code that uses them: For a function, accept the setting as an argument. If you have a struct with methods, even better: Make the setting a field of the struct that needs to be defined. If you have a constructor, have that constructor accept the setting. Pro: No globals, dependencies on settings are clear. Con: It might not be obvious which values are application settings right away, until you trace back their origin.
Number 3 is my favorite method since imho it makes it much more clear where
settings are coming from and how they are being used.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论