我想将一个模块常量的繁重计算放入一个单独的函数中,但这会失败:
defmodule Test do
@test calc_constant()
defp calc_constant do
# Calculation heavy task like building a translation table
end
end
我可以以某种方式做到这一点而无需在模块顶部编写整个计算吗?
答案 0 :(得分:3)
是的,你可以,但你应该把这个功能放在其他模块中。
iex(1)> defmodule A, do: def calc, do: 42
{:module, A, <<70, 79, ...>>, {:calc, 0}}
iex(2)> defmodule B do
...(2)> @a A.calc()
...(2)> def a, do: @a
...(2)> end
{:module, B, <<70, 79, ...>>, {:a, 0}}
iex(3)> B.a
42
原因是:@var
声明在编译阶段完全展开。虽然在同一模块中具有该功能,但您会遇到鸡蛋问题。
旁注:如果有一个常量需要声明,那么另一种方法是提供一个模块,在模块中声明__using__
宏和Kernel.use/2
这样:
defmodule HeavyConstants do
defmacro __using__(_opts) do
quote bind_quoted: [test1: heavy_calc1(), ...] do
@test1 test1
@test2 test2
...
@testN testN
end
end
end
defmodule Test do
use HeavyConstants
# here you have all `N` `@test{1,2,...N}` on hand
end