如何在Elixir上定义共享常量

时间:2017-12-18 03:25:40

标签: elixir

我可以定义模块的常量共享吗?

通常,我们将模块属性用于常量内部模块。 http://elixir-lang.github.io/getting-started/module-attributes.html#as-constants

如果我想让其他模块继续可用,我该怎么办? 首先,模块属性仅在模块(1)内可用。 我知道我可以使用函数作为常量(2)。 但是如果可能的话,我想通过像3这样的专用形式来定义常量。

interface A<T extends A> { T bla();}
class B implements A<B> { @Override public B bla() { return this; } }
class C implements A<C> { @Override public C bla() { return this; } }

后记

我希望恒定满足以下要求。

  • 编译时的评估
  • 按模块分类(I表示常量应在适当的模块中定义)

2 个答案:

答案 0 :(得分:1)

非模块特定常量通常放在config/foo.exs中,并由System.get_env/1Application.get_env/2访问。如果您希望它位于特定模块的下方/内部(而不仅仅是特定的应用程序),原因是只需给它一个合适的名称并使用上述选项之一就无法满足......首先,请确保这是准确的,你有充分的理由,因为我无法想到一个我的头脑。

如果您仍然想要,答案是(AFAIK)只是您的选项-2,即功能。如果您想要一个专用表单,请使用宏:

defmacro const([{name, val}]) do
  quote do
    def unquote(name) do: unquote(val)
  end
end

然后,您可以在您需要的任何模块中执行const foo: 87,并导入其中定义了const的模块。

或者您可以将每个常量定义为宏而不是函数。缺点:您需要require模块。优点:在编译时解析,就像属性一样。虽然没有副作用的arity 0的功能可能会这样做,但我不确定,但这是一个合理的优化。

答案 1 :(得分:0)

您还想查看Module.register_attribute函数。您将此与Module.get_attribute结合使用。我似乎记得有一些关于使用它作为跨模块共享属性的方法。