2013-02-19 56 views
3

我調試錯誤,並發現undefined已追加到列表中,這引起了崩潰以後。未定義追加到列表

我預計追加其他的東西比與++操作列表會導致崩潰。但undefined並非如此。這裏有一個例子:

1> [1,2,3] ++ undefined. 
[1,2,3|undefined] 

雖然它不會崩潰,該列表是沒有充分發揮作用了:

1> L = [1,2,3] ++ undefined. 
[1,2,3|undefined] 
2> L ++ [4]. 
** exception error: bad argument 
    in operator ++/2 
     called as [1,2,3|undefined] ++ [4] 

爲什麼會出現這種情況? 這與erlang中列表的底層實現有關嗎?

+0

因此,與幾個同伴在#@二郎討論Freenode的這個。這是「不正確列表」的一個例子。它有一些好處。考慮一個元組:'{key,value}'。在erlang VM中,這是三個術語。一個術語是兩個元素的元組,另外兩個是術語'key'和'value'。訪問元組時,首先必須對元組術語進行解引用,以訪問它所包含的兩個術語。但是,假設我們將它實現爲不正確的列表:'[key | value]'。使用這種格式,您不必對一個術語進行解引用,並且可以節省一段內存(因爲您不必存儲元組術語)。 – 2013-02-19 20:03:16

+0

這是有效的,因爲Erlang列表是CONS列表,意味着列表中的每個單元格都是一個雙字對,等同於'struct list_cell {Eterm hd; Eterm tl;}'。 '[a | b]'創建一個list_cell,其中hd設置爲原子'a',t1設置爲atom'b'。還應該指出,恐嚇分子可能(並且合法/合理)是不正確的名單。 – 2013-02-19 20:12:49

+1

聲音正確。下面是一些鏈接,解釋不當列表及其用途:http://stackoverflow.com/questions/1919097/functional-programming-what-is-an-improper-list http://stackoverflow.com/questions/5088575/practical在erlang中使用不正確的列表 - 也許是所有功能語言 – Isac 2013-02-19 20:14:45

回答

1

原因是++將第二個參數追加到其第一個參數的末尾,其中必須是是一個列表。它不會對其第二個參數進行任何處理,它只是按原樣追加它。所以:

1> [1,2,3] ++ undefined. 
[1,2,3|undefined] 
2> [1,2,3] ++ [undefined]. 
[1,2,3,undefined] 

你可以做到這一點,以及其原因:

3> [a|b]. 
[a|b] 
4> [a|[b]]. 
[a,b] 

是一個列表是序列表中的細胞,一個單鏈表,不是一個單一的數據結構,例如。如果右手邊,叫,每個細胞是另一個列表細胞或[]那麼你得到一個正確的名單。每個單元格的左側稱爲頭部,通常包含列表中的元素。這是我們在上面2和4中所具有的。大多數(如果不是全部的話)庫函數假定列表是適當的列表,並且如果它們不是,則會產生錯誤。請注意,您必須實際將整個列表逐步放到最後才能查看是否正確。

每個列表單元格都寫爲[Head|Tail],語法[a,b,c]只是[a|[b|[c|[]]]]的語法糖。請注意,每個列表單元格的尾部是一個列表或[],所以這是一個正確的列表。

沒有任何限制,以什麼列表單元的頭部和尾部的類型即可。系統從不檢查它只是做它。這是我們在上面的1和3中最後一個列表單元格的尾部(僅3列表單元格)不是列表或[]

對不起,在這裏有點過度教學。

編輯:我看到,我已經描述了這樣的位置:Functional Programming: what is an "improper list"?

1

在Erlang中,所有的術語是由稱爲Eterm緊湊類指針值表示。看起來,列表操作函數被實現爲類型不可知的。

從這個角度考慮:在erlang虛擬機內部,所有Eterms都是相等的。頭部和尾部列表操作操作的速度非常快。由於需要幾個操作來評估不透明的Eterm類型以確定它是否是列表,爲什麼要麻煩?

在這種情況下的預期結果是一個錯誤,你會得到一個。最終。

對於信任程序員有些事情要說,而且在處理增加幾個週期並且經常使用的操作時,忽略壞追加的潛在好處就會疊加起來,唯一的損失是一個奇怪的錯誤。

+0

我知道這一點。我的問題是:爲什麼'[1,2,3] ++ undefined'不會崩潰? – Isac 2013-02-19 16:54:27

+0

對不起,誤解了你的問題。用我最好的猜測更新了我的答案,但我不知道確切的答案。 – 2013-02-19 16:56:05

+0

@Isac:想知道一些有趣的事情嗎?它似乎與任何數據類型發生。我用不同的原子,整數和浮點數來試用它。沒有人抱怨手術,後來都沒有看清表。 – 2013-02-19 17:07:57