Elixir 是動態型別的語言,也就是說,變數的型別只會在執行時檢查。使用匹配運算子=,我們可以把任意型別的值綁定到一個變數名稱上:
# Bound an integer value of 1
count = 1
# You may re-bind variables
count = 2
# You may re-bind any type to a variable
count = false
# Strings can be created by enclosing characters within double quotes
message = "Success!"
Elixir 是函式程式設計語言,所有具名函式都必須定義在_模組_中。defmodule關鍵字用來定義模組。在執行時,所有模組都可以被其他模組取用,不需要_存取修飾子_就能讓程式的其他部分看見它們。模組_概念上類似於其他程式語言中的_類別。
defmodule Calculator do
# ...
end
_具名函式_必須定義在模組中。def關鍵字用來定義_公開_的具名函式。
每個函式可以有零個或多個引數。函式中最後一個運算式的值總是會_被隱式回傳_。
defmodule Calculator do
def add(x, y) do
x + y
end
end
呼叫函式時,要指定它的模組和函式名稱,並為函式的每個參數傳入引數。
sum = Calculator.add(1, 2)
# => 3
也可以用defp關鍵字取代def來定義_私有_函式。私有函式只能在定義它們的同一個模組內使用。
當在定義函式的同一個模組內呼叫它時,可以省略模組名稱。
你也可以用單行語法撰寫簡短的函式(注意關鍵字do前後的逗號,和冒號:)。
defmodule Calculator do
def subtract(x, y) do
private_subtract(x, y)
end
defp private_subtract(x, y), do: x - y
end
difference = Calculator.subtract(7, 2)
# => 5
difference = Calculator.private_subtract(7, 2)
# => ** (UndefinedFunctionError) function Calculator.private_subtract/2 is undefined or private
# Calculator.private_subtract(7, 2)
我們常會用_引數個數_來指稱函式。函式的_引數個數_就是它接受的引數數量。
# add/3 because this function has three arguments, thus an arity of 3
def add(x, y, z) do
x + y + z
end
模組名稱應該使用PascalCase。模組名稱必須以大寫字母A-Z開頭,可以包含字母a-zA-Z、數字0-9和底線_。
變數和函式名稱應該使用snake_case。變數或函式名稱必須以小寫字母a-z或底線_開頭,可以包含字母a-zA-Z、數字0-9和底線_,而且結尾可以是問號?或驚嘆號!。
Elixir 擁有非常豐富且文件完整的標準函式庫。文件可以在 hexdocs.pm/elixir 線上查閱。把這個連結存起來,你會很常用到它喔!
大多數內建的資料型態都有對應的模組,提供處理該型別的函式。例如整數有Integer模組,字串有String模組,陣列有List模組等等。
值得一提的模組是Kernel模組。它是標準函式庫其餘部分的建構基礎,提供算術運算子、控制流程巨集等基本能力。Kernel模組的函式會自動匯入,所以你可以不加Kernel.前綴直接使用。
註解可以用來留下筆記,給閱讀原始碼的其他開發者參考。Elixir 的單行註解以#開頭。
在這道練習中,你會寫一些程式碼,幫助你依照最愛的食譜書做出一份美味的千層麵。
你有五個任務,全都和烹調千層麵所花費的時間有關。
定義Lasagna.expected_minutes_in_oven/0函式,這個函式不接受任何引數,並回傳千層麵應該在烤箱中待幾分鐘。根據食譜書,預期的烤箱時間為 40 分鐘:
Lasagna.expected_minutes_in_oven()
# => 40
定義Lasagna.remaining_minutes_in_oven/1函式,這個函式接受千層麵已經在烤箱中的實際分鐘數作為引數,並根據上一個任務算出的預期烤箱時間(分鐘),回傳千層麵還需要在烤箱中待幾分鐘。
Lasagna.remaining_minutes_in_oven(30)
# => 10
定義Lasagna.preparation_time_in_minutes/1函式,這個函式接受你加到千層麵中的層數作為引數,並回傳你準備千層麵花了幾分鐘,假設每一層需要花你 2 分鐘準備。
Lasagna.preparation_time_in_minutes(2)
# => 4
定義Lasagna.total_time_in_minutes/2函式,這個函式接受兩個引數:第一個引數是你加到千層麵中的層數,第二個引數是千層麵已經在烤箱中的分鐘數。這個函式應該回傳你總共花了幾分鐘烹調千層麵,也就是備料時間(分鐘)加上千層麵當下已經在烤箱中待的分鐘數。
Lasagna.total_time_in_minutes(3, 20)
# => 26
定義Lasagna.alarm/0函式,這個函式不接受任何引數,並回傳一則訊息,表示千層麵已經可以吃了。
Lasagna.alarm()
# => "Ding!"