在Ruby中,如果一个人在类中定义常量,他们将使用全部大写来定义它们.例如:
class MyClass
MY_FAVORITE_NUMBER = 13
end
Run Code Online (Sandbox Code Playgroud)
你是怎么做到Elixir的?如果不存在这样的等价物,你如何解决Elixir中的魔法数字问题?
AbM*_*AbM 45
您可以在前面添加变量名称@:
defmodule MyModule do
@my_favorite_number 13
end
Run Code Online (Sandbox Code Playgroud)
这是文档
Ale*_*arf 12
环顾 github,我看到有人在使用它,这对我很有吸引力。允许从其他模块访问常量。
ModuleA
@my_constant 23
defmacro my_constant, do: @my_constant
ModuleB
Require ModuleA
@my_constant ModuleA.my_constant
Run Code Online (Sandbox Code Playgroud)
又是一个简单而引人入胜的灵丹妙药解决方案
另一种定义常量的方法是我使用wxErlang头文件.也就是说,您可以简单地定义一个单行函数,为您返回常量值.像这样:
def wxHORIZONTAL, do: 4
def wxVERTICAL, do: 8
def wxBOTH, do: (wxHORIZONTAL ||| wxVERTICAL)
Run Code Online (Sandbox Code Playgroud)
这是来自相同源代码的另一个例子:
# From "defs.h": wxDirection
def wxLEFT, do: 16
def wxRIGHT, do: 32
def wxUP, do: 64
def wxDOWN, do: 128
def wxTOP, do: wxUP
def wxBOTTOM, do: wxDOWN
def wxNORTH, do: wxUP
def wxSOUTH, do: wxDOWN
def wxWEST, do: wxLEFT
def wxEAST, do: wxRIGHT
def wxALL, do: (wxUP ||| wxDOWN ||| wxRIGHT ||| wxLEFT)
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,根据另一个常量定义常量会更容易一些.当我想要在不同模块中使用这些常量时,我需要做的就是require WxConstants在模块的顶部.这使得在一个地方定义一个常量并在其他几个地方使用它更加容易 - 对DRY有很大的帮助.
顺便说一下,如果你很好奇,你可以在这里看到回购.
正如我所说,为了完整起见,我补充这个答案.
Elixir模块可以具有关联的元数据.元数据中的每个项称为属性,并通过其名称访问.您可以使用在模块内定义它@name value.并被访问为@name
defmodule Example
@site 'StackOverflow' #defining attribute
def get_site do
@site #access attribute
end
end
Run Code Online (Sandbox Code Playgroud)
记住这只适用于模块的顶层,你不能在函数定义中设置模块属性.
也许您定义了一个常量模块文件,并且可以在其中定义宏,如下所示
defmodule MyApp.Constants do
defmacro const_a do
quote do: "A"
end
end
Run Code Online (Sandbox Code Playgroud)
您可以通过将其导入任何其他模块来使用它
defmodule MyApp.ModuleA do
import MyApp.Constants
def get_const_a do
const_a()
end
end
Run Code Online (Sandbox Code Playgroud)
好处还在于,您不会招致任何运行时成本,也不会在匹配情况下使用它
case something do
const_a() -> do_something
_ -> do_something_else
end
Run Code Online (Sandbox Code Playgroud)