send_stuff(Socket, ListOfMessages) ->
Send = fun(Message) -> ok = gen_tcp:send(Socket, Message) end,
lists:foreach(Send, ListOfMessages).
リスト操作の各反復:私は「いくつかのデータを送信する」のより一般的な操作のうち、その値をカリー化する効果があるラムダの本体、内ソケットの値を超える閉じることができますlists:foreach/2
は、第1引数としてアーリー1の関数しか受け入れることができません。私たちはSocket
の値を既に内部で取得している(これは既に外側スコープにバインドされていたため)クロージャを作成し、バインドされていない内部変数Message
と組み合わせています。また、gen_tcp:send/2
がラムダ内で毎回働いているかどうかを確認するには、戻り値gen_tcp:send/2
が、実際にはok
だったと主張します。
これは、超有用な特性です。
だから、このことを念頭に置いて、のはあなたのコードを見てみましょう:あなた上記のコードで
1> Total = 15.
2> Calculate = fun(Number)-> Total = 2 * Number end.
3> Calculate(6).
はちょうどあなたがちょうど私達のような、その値のラベルを(作成している意味、Total
に値を割り当てました上記の例ではSocket
が割り当てられていました)。結果は15.0
、ない15
になるので、Total
はそう2 * 7.5
はどちらかそれをカットしないと、整数だったので本当であることはできません - その後、あなたははTotal
の値は2 * Number
の結果があるかもしれないものは何でもあるを主張しています。この例では
1> Calculate = fun(Number)-> Total = 2 * Number end.
2> Total = 15.
3> Calculate(6).
は、しかし、あなたは外側のスコープで宣言された任意の値を超える閉じないTotal
呼ば内部変数を持っています。後ではTotal
と呼ばれる外側スコープ内のラベルを宣言するですが、今回は最初の行のラムダ定義が抽象関数に変換され、ラベルTotal
が不変のスペースに完全に渡されています新しい関数定義のCalculate
への代入が表されます。したがって、競合はありません。 はリスト内包から内側の値を参照しようとすると、例えば、何が起こるか考えてみましょう:
1> A = 2.
2
2> [A * B || B <- lists:seq(1,3)].
[2,4,6]
3> A.
2
4> B.
* 1: variable 'B' is unbound
これは、あなたがPythonの2、たとえば、に期待するものではありません。
>>> a = 2
>>> a
2
>>> [a * b for b in range(1,4)]
[2, 4, 6]
>>> b
3
ちなみに、これはPythonの3で修正されています:
>>> a = 2
>>> a
2
>>> [a * b for b in range(1,4)]
[2, 4, 6]
>>> b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
(そして、私はJavaScripを提供しますたとえ比較のための例であっても、スコープ規則はそれほど絶対に狂っていてもそれは問題ではない...)
これは、より明確な答えであるため、範囲(コンテキスト)に関する情報を追加する必要があります。 「検索表」は必ずしも理解しやすいものではありません。いくつかのリンク:http://learnyousomeerlang.com/higher-order-functions、http://www.erlang.org/course/advanced#scope、http://icai.ektf.hu/pdf/ICAI2007-vol2-pp137 -145.pdf –
@Atomic_alarm:あなたが正しいのではないか:o)シェルの動作とモジュールコードの小さな違いがあるので、実際にはこのテーブル(シェルと並行して動作するプロセス辞書)特にシェル内の変数f(Foo)を「忘れる」ことが可能であるという事実を私は常に抱きしめてきました。しかし、それは正しいです、それは私の答えを理解するのに役立つ、私はモジュール内で同じ動作することを言及する必要があると感じた... – Pascal