在 Elixir 中,函式是一級公民。這代表:
與具名函式不同,匿名函式沒有可靜態參照的名稱,只有在賦值給變數或立即呼叫時才能使用。
我們可能會用匿名函式來:
匿名函式以保留字 fn 開頭,引數和函式主體之間以 -> 符號分隔,並以 end 結束。和具名函式一樣,函式中最後一個運算式會_隱式回傳_給呼叫它的函式。
若要呼叫函式參照,必須在參照變數和引數列表之間使用 .:
function_variable = fn param ->
param + 1
end
function_variable.(1)
# => 2
你還可以使用簡寫的擷取語法,讓這段程式碼更簡潔:
variable = &(&1 + 1)
variable.(1)
# => 2
Elixir 在 _Bitwise 模組_中提供了許多處理位元的函式。
band/2:位元 ANDbsl/2:位元左移bsr/2:位元右移bxor/2:位元 XORbor/2:位元 ORbnot/1:位元 NOT以下是使用位元函式的範例:
Bitwise.bsl(1, 3)
# => 8
所有位元函式都只能處理整數。
如果你執行的是 Elixir 1.9 或更早的版本,需要在模組定義的開頭呼叫 require Bitwise,才能使用 Bitwise 模組。
在這個練習中,你的任務是為一台加密裝置撰寫軟體,這台裝置的運作方式是對資料進行轉換。你需要一種方法,能透過組合較簡單的函式,靈活地建立複雜的函式。
每個任務都要回傳一個匿名函式,且該函式可以從呼叫端的作用域中呼叫。
所有函式都應接受整數引數。在 Elixir 中,整數也很適合用來執行位元運算。
實作 Secrets.secret_add/1。它應該回傳一個函式,該函式接受一個引數,並將傳入 secret_add 的引數加到這個引數上。
adder = Secrets.secret_add(3)
adder.(2)
# => 5
實作 Secrets.secret_subtract/1。它應該回傳一個函式,該函式接受一個引數,並從該引數中減去傳入 secret_subtract 的秘密。
subtractor = Secrets.secret_subtract(2)
subtractor.(3)
# => 1
實作 Secrets.secret_multiply/1。它應該回傳一個函式,該函式接受一個引數,並將它乘以傳入 secret_multiply 的秘密。
multiplier = Secrets.secret_multiply(7)
multiplier.(3)
# => 21
實作 Secrets.secret_divide/1。它應該回傳一個函式,該函式接受一個引數,並將它除以傳入 secret_divide 的秘密。
divider = Secrets.secret_divide(3)
divider.(32)
# => 10
請使用整數除法,讓輸出能與其他函式預期的輸入相容。
實作 Secrets.secret_and/1。它應該回傳一個函式,該函式接受一個引數,並對它和傳入 secret_and 的秘密執行位元 and 運算。
ander = Secrets.secret_and(1)
ander.(2)
# => 0
實作 Secrets.secret_xor/1。它應該回傳一個函式,該函式接受一個引數,並對它和傳入 secret_xor 的秘密執行位元 xor 運算。
xorer = Secrets.secret_xor(1)
xorer.(3)
# => 2
實作 Secrets.secret_combine/2。它應該回傳一個函式,該函式接受一個引數,並依序將傳入 secret_combine 的兩個函式套用到它上面。
add_one = Secrets.secret_add(1)
multiply_by_2 = Secrets.secret_multiply(2)
combined = Secrets.secret_combine(add_one, multiply_by_2)
combined.(3)
# => 8