2016-07-16 17 views
2

Ich versuche Erlang zu lernen. Hier ist ein Basisserver, der die Fläche des Quadrats berechnet. Es ist eine modifizierte Version des Beispiels 6 der erlang white papererlang - empfange Loopmuster passendes Problem

Hier ist der Code:

-module(area_server). 
-export([start/0, loop/0]). 

start() -> 
    spawn(area_server, loop, []). 

loop() -> 
    receive 
     {Client, {square, X}} -> 
      Client ! X*X, 
      loop() 
    end. 

Das Problem, das ich habe ist, dass es scheint, dass ich X nur einen Wert binden kann. Die Bindung an einen anderen Wert funktioniert nicht. Zum Testen habe ich folgenden Code:

Server = area_server:start(). 

%Works and returns 100 
Server ! {self(), {square, 10}}, receive Area -> Area end. 

%Does not work and just does not return at all 
Server ! {self(), {square, 5}}, receive Area -> Area end. 

Also wie kann ich Quadrat von 5 berechnen?

+2

Ok. Es scheint also, dass das Problem nicht im Server, sondern im Client-Code liegt. Da ich in eine Variable mit dem Namen 'Area' empfangen habe und sie einmal an 100 gebunden ist, kann sie danach nicht an 25 gebunden werden. Wenn ich also im zweiten Aufruf zu' Area1' wechsel, funktioniert es. – arahant

Antwort

2

Was passiert hier ist, dass auf dem zweiten Lauf Area ist bereits begrenzt.

Wenn Sie das tun:

recieve Area -> Area end. 

Der erste Area empfängt den Wert und die zweiten Area begrenzt den Wert auf die Variable (Area). Also nach dem ersten Anruf wird Area mit dem Wert 100 gebunden.
Wie Sie vielleicht bereits wissen, ist Erlang eine einzige Assignment-Sprache. Weitere Informationen finden Sie unter this und this.

Wenn Sie dies zum zweiten Mal mit der gleichen Area Variable ausführen, wartet es auf den receive Aufruf, weil es keine Übereinstimmung gibt. Der Wert, den Sie senden, ist 25, aber die Area innerhalb des Empfangs ist bereits auf 100 begrenzt, so dass es keine Übereinstimmung gibt. Das ist der Grund, warum es einfach dort hängt.

Wenn Sie diese arbeiten möchten, können Sie eine Funktion zum Beispiel erstellen:

get_area(Server, Amount) -> 
    Server ! {self(), {square, Amount}}, receive Area -> Area end. 

Und dann im Client nur get_area(Server, 10) oder get_area(Server, 5) nennen.