use運算式在 Gleam 裡,撰寫並使用高階函式是很常見的事,也就是把其他函式當作引數的函式。有時候同時使用很多高階函式,程式碼會變得難以閱讀,出現一層又一層的縮排。
舉例來說,底下這個函式會呼叫好幾個回傳Result(Int, Nil)的函式,並在四個都成功時把它們的值加總。
import gleam/result
pub fn main() -> Result(Int, Nil) {
result.try(function1(), fn(a) {
result.try(function2(), fn(b) {
result.try(function3(), fn(c) {
result.try(function4(), fn(d) {
Ok(a + b + c + d)
})
})
})
})
}
Gleam 的use運算式讓我們可以不用縮排就寫出這段程式碼,通常也讓程式更好讀。
import gleam/result
pub fn main() -> Result(Int, Nil) {
use a <- result.try(function1())
use b <- result.try(function2())
use c <- result.try(function3())
use d <- result.try(function4())
Ok(a + b + c + d)
}
一個use運算式會收集程式區塊中後續的所有敘述,並把它當作回呼函式,作為最後一個引數傳給函式呼叫。use關鍵字和<-符號之間的變數,就是將會傳給回呼函式的引數名稱。
// This use expression
use a <- function(1, 2)
io.println("Hello!")
a
// Is equivalent to this normal function call
function(1, 2, fn(a) {
io.println("Hello!")
a
})
回呼函式可以接受任意數量的引數,也可以完全不接受引數。
use a, b, c, d <- call_4_function()
use <- call_0_function()
要建立一個能用use運算式呼叫的函式,並沒有什麼特別的要求,只要它把回呼函式當作最後一個引數就好。
pub fn call_twice(function: fn() -> t) -> #(t, t) {
let first = function()
let second = function()
#(first, second)
}
Gleam 的use運算式是非常強大的功能,可以運用在很多問題上,但如果過度使用,反而會讓程式碼難以閱讀。一般來說,比較建議使用一般的函式呼叫語法,只有在use運算式能讓程式碼更好讀時才用它。
Daphne 一直在開發一套系統,用來執行並記錄她實驗的結果。有些程式碼變得有點冗長、重複,所以她請你寫幾個use運算式來幫忙整理。
with_retry函式有時候實驗可能會因為一次偶發的失誤而失敗,所以如果實驗失敗了,Daphne 想再重試一次,看看第二次是否會成功。
定義with_retry函式,它接受一個會回傳結果的函式作為引數。
如果這個函式回傳Ok值,with_retry就應該回傳那個值。
如果這個函式回傳Error值,with_retry就應該再次呼叫這個函式,並回傳那次呼叫的結果。
Daphne 會這樣使用這個函式:
pub fn main() {
use <- with_retry
// Perform the experiment here
}
record_timing函式Daphne 會在每個實驗前後呼叫記錄時間的函式,藉此記錄每個實驗執行所需的時間。
定義record_timing函式,它接受兩個引數:
Nil。record_timing應該先呼叫記錄時間的函式,接著呼叫實驗函式,然後再次呼叫記錄時間的函式,最後回傳實驗函式的結果。
Daphne 會這樣使用這個函式:
pub fn main() {
use <- record_timing(time_logger)
// Perform the experiment here
}
run_experiment函式實驗由三個階段組成:設定、動作與記錄。三個階段都會回傳結果,而且每個階段都需要前一個階段成功回傳的結果才能執行。
定義run_experiment函式,它接受四個引數:
String。Ok值作為引數,並回傳結果。Ok值作為引數,並回傳結果。如果三個函式都成功,run_experiment應該回傳Ok(#(experiment_name, recording_data))。
如果其中任何一個函式回傳Error值,run_experiment就應該回傳那個值。
Daphne 會這樣使用這個函式:
pub fn main() {
use setup_data, action_data <- run_experiment("Test 1", setup, action)
// Record the results here
}