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でのリストの基本的な実装に関連していますか?

4

2 に答える 2

1

Erlangでは、すべての用語は、と呼ばれるコンパクトなポインタのような値で表されますEterm。リスト操作関数はタイプに依存しないものとして実装されているようです。

この観点から考えてみてください。erlangVM内では、すべてのEtermが同じです。ヘッドリストとテールリストの操作操作は非常に高速であると請求されます。不透明(OPAQUE Eterm)型を評価してリストかどうかを判断するにはいくつかの操作が必要なので、なぜわざわざするのでしょうか。

このような状況で予想される結果はエラーであり、実際にエラーが発生します。最終的。

プログラマーを信頼するために言わなければならないことがあります。数サイクルを追加して頻繁に使用される操作を処理する場合、不正な追加を無視することの潜在的な利点が積み重なって、唯一のペナルティは奇妙なエラーです。

于 2013-02-19T16:52:39.097 に答える
1

その理由は、リストでなければならない++最初の引数の最後に2番目の引数を追加するためです。2番目の引数の処理は行わず、そのまま追加するだけです。それで:

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のリストセルのみ)の末尾がリストまたはではありません[]

ここで少し過大な教訓を得て申し訳ありません。

編集:私はすでにこれをここで説明していることがわかります:関数型プログラミング:「不適切なリスト」とは何ですか?

于 2013-02-20T13:43:04.253 に答える