【问题标题】:Composing Attributes in Elixir在 Elixir 中组合属性
【发布时间】:2015-11-04 23:43:56
【问题描述】:

由于一旦编译模块就内联了属性,我假设它们的值是恒定的。如果可能的话,我想根据以前创建的属性来定义一个属性。我也希望能够从外部访问它们,我目前的做法是这样的

@required_fields ~w(email)
@optional_fields ~w(password role name last_name age country)

def required_fields, do: @required_fields
def optional_fields, do: @optional_fields

@all_fields required_fields ++ optional_fields
def all_fields, do: @all_fields

但我收到此错误

== 文件 web/models/user.ex 上的编译错误 == ** (CompileError) web/models/user.ex:22: 未定义函数 required_fields/0 (elixir) 扩展宏:Kernel.@/1 web/models/user.ex:22:AristaServer.User(模块) (elixir) lib/kernel/parallel_compiler.ex:97: Kernel.ParallelCompiler.spawn_compilers/8 中的匿名 fn/4

有什么方法可以达到类似的效果吗?我不想每次都重新计算all_fields 列表,似乎很浪费。另外,我不想将两个列表都复制并传递到第三个列表中,这看起来很容易出错。

【问题讨论】:

    标签: elixir


    【解决方案1】:

    除非您运行过基准测试,否则您对 elixir 中什么是“浪费”的直觉可能是错误的。我知道我运行的每个基准测试都是如此。 只需执行此操作,然后担心它工作后什么是快或慢。

     def all_fields, do: required_fields ++ option_fields
    

    https://en.wikiquote.org/wiki/Donald_Knuth

    我的想法是使用模块属性可能会更浪费内存,因为它们会在代码中转换为多个项目。如果将其保留在变量中,则它只会在内存中创建一次。但这只是一个猜测。

    但是如果你真的想组合模块属性,你可以这样做。

    @all_fields @required_fields ++ @optional_fields
    def all_fields, do: @all_fields
    

    您的问题出现是因为您不能使用模块中的函数来定义模块属性。

    【讨论】:

    • Elixir 对这种特殊情况有记忆吗?如果不是,我无法想象它会如何加快 all_fields 并避免调用 O(n) 的 ++ 运算符。
    • ++ 运算符只有 0(n) 与可变数据。如果数据项是不可变的 ++ 是 0(1),(即当您到达此列表的末尾时,从下一个列表开始。)。我不知道这是否真的是 ++ 的实现方式,但它是一个例子,说明在不可变的数据环境中,你对什么是快速的所有直觉是如何被抛到窗外的。
    • 我深入研究了代码,x ++ y 是 O(x 的大小),所以它介于两者之间。它复制 x,然后将 x 的尾部指向 y 的头部。
    【解决方案2】:
    @required_fields    ~w(email)
    @optional_fields    ~w(password role name last_name age country)
    @all_fields         @required_fields ++ @optional_fields
    
    
    def required_fields, do: @required_fields
    def optional_fields, do: @optional_fields
    def all_fields,      do: @all_fields
    

    我怀疑你需要模块属性和公共方法;考虑只使用一个(如果你只在模块中使用它们,模块属性应该可以完成这项工作,否则你应该使用公共方法)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多