2015-11-04 62 views
0

由於在編譯模塊後內聯屬性,我假設它們的值是恆定的。如果可能的話,我想根據以前創建的屬性來定義一個屬性。我也希望能夠從外部訪問它們,我目前的做法是這樣的在Elixir中編寫屬性

@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 /模型/ user.ex = = **(CompileError)web/models/user.ex:22:undefined function required_fields/0 (elixir)展開宏:Kernel。@/1 web/models/user.ex:22:AristaServer.User(module ) (elixir)lib/kernel/parallel_compiler.ex:97:Kernel.ParallelCompiler.spawn_compilers/8中的anonymous fn/4

任何方式來實現類似的東西?我不想每次重新計算all_fields列表,看起來很浪費。另外,我不想將這兩個列表複製並複製到第三個列表中,看起來很容易出錯。

回答

1

除非你運行了一個基準測試,否則你對靈丹藥劑中「浪費」的直覺可能是錯誤的。我知道,我已經運行過的每個基準都是這種情況。 只要做到這一點,並擔心它的工作後快或慢。

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 

您的問題出現了,因爲您無法使用模塊中的函數來定義模塊屬性。

+0

Elixir對這種特殊情況有記憶嗎?如果不是,我無法想象它將如何加速'all_fields'並避免調用O(n)的'++'運算符。 –

+0

++運算符只有可變數據的0(n)。如果數據項是不可變的,則++爲0(1),(即當你到達這個列表的末尾時,從下一個列表開始)。我不知道這實際上是如何實現++的,但它是一個例子,說明在不變數據環境中,所有關於快速什麼的直覺都會被拋出窗口。 –

+0

我挖入代碼,'x ++ y'是O(x的大小),所以它介於兩者之間。它複製x,然後將x的尾部指向y的頭部。 –

1
@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 

我懷疑你需要兩個模塊屬性和公共方法;考慮只使用一個(如果你只在模塊中使用它們,模塊屬性應該做這個工作,否則你應該使用公共方法)。