我是Elixir / Erlang编程的新手。
如何为Elixir模块实现模块属性,因此模块的用户可以在模块构造函数中设置。
例如,
defmodule Config do
some_property: nil
other_property: nil
def constructor(one, two) do
some_property = one
other_property = two
end
def get_property_one do
some_property
end
end
谢谢
答案 0 :(得分:6)
Elixir模块不是类,它们内部定义的变量不是属性,因此没有构造函数和析构函数之类的东西。 Elixir基于Erlang,所以首先,我会推荐一些关于Erlang和面向对象编程的阅读:
这应该为您提供基本的想法,为什么不支持具有getter和setter的对象。使对象具有状态的最接近的事情是具有状态的server。所以在服务器循环中,你可以这样做:
def loop(state) do
newstate = receive do
{ :get_property_one, pid } ->
pick_the_property_from_state_and_send_to_pid(state, pid)
state
{ :set_property_one } ->
set_property_one_and_return_new_state(state)
end
loop(newstate)
end
使用构造函数生成具有初始状态的新服务器即将创建新对象。发送:get_property_one
就像getter一样,但是异步(你可以在等待回复之前做一些其他事情)。发送:set_property_one
并不等待回复,因此它不会阻止。
这可能看起来很麻烦,但它解决了几个问题:
这种模式很常见,有behaviour
called gen_server
,它消除了大部分循环的样板。如果您仍然认为,要编写的样板太多,您可以阅读my article about it(这个是在Erlang中)
答案 1 :(得分:1)
我认为你最接近OO
的是
defmodule Config do
defstruct [
some_property: nil,
other_property: nil
]
def new(one, two) do
%Config{
some_property: one,
other_property: two
}
end
#Getter
def property_one(this) do
this.some_property
end
#Setter
def property_one(this, value) do
%{this | some_property: value}
end
end
你必须像这样使用它
conf = Config.new("a", 2)
Config.property_one(conf) # == "a"
conf = Config.property_one(conf, "b") # == %Config{some_property: "b", other_property: 2}
如您所见,它们只是提取/集成一些信息到/结构中的函数。我喜欢C#和Dart中的getter和setter,但是在FP世界中它们只是函数,不多也不少。