假設 函數A 是個遞回函數,當我們在外部呼叫 函數A 時,在函數A在滿足條件的情況下會一直自己呼叫自己
簡單的說:函數自己呼叫自己
我們在超市買了一些東西,當去櫃檯結賬時,通過呼叫模組的函數 計算出商品的總價格
Items = [{orange,4},{apple,10},{pear,6}].
%% 結賬模組 price.erl
-module(price).
-export({sum/1}).
%% 單個商品對應的價格
itemPrice(orange) -> 0.5;
itemPrice(apple) -> 1;
itemPrice(pear) -> 0.8;
%% 遞回函數1
%% 只要傳遞進來的列表中,有一個商品,就匹配成功
%% |--一種商品--||--剩餘商品--| |---計算該商品消費金額----| |--遞回呼叫,計算剩餘商品價格--|
sum([{Item, ItemNum}|ItemList]) -> itemPrice(Item) * ItemNum + sum(ItemList);
%% 遞回函數2
%% 如果傳遞進來的列表是個空列表,函數執行結束
sum([]) -> 0.
> erl
> c(price).
> price:sum([{orange,4},{apple,10},{pear,6}]).
16.8
我們詳細分解下遞回函數的呼叫
在erlangShell中呼叫時,函數是怎麼執行的
%% 參數:[{orange,4}|{apple,10},{pear,6}]
%% 從上往下對函數 sum 進行模式匹配
%% 第一個函數匹配成功:sum([{Item, ItemNum}|ItemList])
%% Item=orange,ItemNum=4,ItemList = [{apple,10},{pear,6}]
sum([{orange,4}|{apple,10},{pear,6},{milk,3}])) ->
%% 這裏只是單純的計算價格
itemPrice(orange) * 4 %% 橘子2元
%% 遞回呼叫,計算下一個商品的價格
+ sum([{apple,10},{pear,6}]).
%% 第一次遞回呼叫
%% 參數:[{apple,10},{pear,6}]
%% 從上往下對函數 sum 進行模式匹配
%% 第一個函數匹配成功:sum([{Item, ItemNum}|ItemList])
%% Item=apple,ItemNum=10,ItemList = [{pear,6}]
sum([{apple,10}|{pear,6}])) ->
%% 這裏只是單純的計算價格
itemPrice(apple) * 10 %% 蘋果10元
%% 遞回呼叫,計算下一個商品的價格
+ sum([{pear,6}]).
%% 第二次遞回呼叫
%% 參數:[{pear,6}]
%% 從上往下對函數 sum 進行模式匹配
%% 第一個函數匹配成功:sum([{Item, ItemNum}|ItemList])
%% Item=pear,ItemNum=6,ItemList = []
sum([{pear,6}|{}])) ->
%% 這裏只是單純的計算價格
itemPrice(pear) * 6 %% 梨4.8元
%% 遞回呼叫,計算下一個商品的價格
+ sum([]).
%% 第三次遞回呼叫
%% 參數:[]
%% 從上往下對函數 sum 進行模式匹配
%% 第一個函數匹配失敗
%% 第二個函數匹配成功
sum([]) -> 0.
%% 最終結果
%% 外部呼叫時得到:橘子2元
%% 第一次遞回呼叫得到:蘋果10元
%% 第二次遞回呼叫得到:梨4.8元
%% 第三次遞回呼叫得到:結束
sum([{orange,4}|{apple,10},{pear,6},{milk,3}])) ->
橘子2元 + 蘋果10元 + 梨4.8元 + 0.