閉包

badge

Erg子例程有一個稱為"閉包"的功能,可以捕獲外部變量

outer = 1 f x = outer + x assert f(1) == 2

與不可變對象一樣,可變對象也可以被捕獲

sum = !0 for! 1..10, i => sum.add!i assert sum == 45 p!x= sum.add!x p!(1) assert sum == 46

但是請注意,函數不能捕獲可變對象 如果可以在函數中引用可變對象,則可以編寫如下代碼

# !!! 這段代碼實際上給出了一個錯誤!!! i = !0 f x = i + x assert f 1 == 1 i.add! 1 assert f 1 == 2

該函數應該為相同的參數返回相同的值,但假設被打破了 請注意,i僅在調用時進行評估

如果您想在定義函數時獲取可變對象的內容,請調用.clone

i = !0 immut_i = i.clone().freeze() fx = immut_i + x assert f 1 == 1 i.add! 1 assert f 1 == 1

avoid mutable state, functional programming

# Erg sum = !0 for! 1..10, i => sum.add!i assert sum == 45

上面的等效程序可以用Python編寫如下:

# Python sum = 0 for i in range(1, 10): sum += i assert sum == 45

但是,Erg 建議使用更簡單的表示法 與其使用子例程和可變對象來傳遞狀態,不如使用一種使用函數來定位狀態的風格。這稱為函數式編程

# 功能風格 sum = (1..10).sum() assert sum == 45

上面的代碼給出了與之前完全相同的結果,但是您可以看到這個代碼要簡單得多

fold函數可以用來做比sum更多的事情 fold是一個迭代器方法,它為每次迭代執行參數f 累加結果的計數器的初始值在init中指定,并在acc中累加

# 從0開始,結果會 sum = (1..10).fold(init: 0, f: (acc, i) -> acc + i) assert sum == 45

Erg被設計為對使用不可變對象進行編程的自然簡潔描述