Come si costruisce il valore di ritorno finale ...
Quando [Msg | important()]
viene restituita per la prima volta, sotto forma di valore di ritorno finale è determinato. L'unica preoccupazione è che non conosciamo ancora tutti i dettagli del valore di ritorno finale. Pertanto locontinuerà a essere valutato. Quanto segue è un'illustrazione di come viene costruito il valore di ritorno finale [high,high,low,low]
.
[high | important( )] <---- Defines the final form
---------------------------------
[high | important( )] <---- Adds more details
------------------------
normal( ) <---- Adds more details
------------------------
[low | normal( )] <---- Adds more details
----------------
[low | normal()] <---- Adds more details
--------
[ ] <---- Adds more details
------------------------------------------
[high | [high | [low | [low | []]]]]
[high,high,low,low] <---- The final return value
Come funziona il codice ...
In funzione important/0
, after 0
significa semplicemente "Non mi aspetto che i messaggi a venire" - se c'è qualche messaggio nella mia casella di posta, ho lo guarderà; se non ce n'è, continuerò ad andare avanti (esegui normal()
) invece di aspettare lì.Nella casella di posta, ci sono {15, alta}, {7, bassa}, {1, bassa}, {17, alta} già seduti lì. In Erlang, i messaggi nella casella postale sono Non in coda in un ordine first-come-first-serve. La clausola receive
può essere pignola. Esamina tutti i messaggi nella casella di posta e "preleva" quelli che desidera. Nel nostro caso, {15, high} e {17, high} vengono prelevati per primi in base allo {Priority, Msg} when Priority > 10
. Dopo questo, la funzione normal/0
prende il sopravvento. E {7, low}, {1, low} vengono elaborati (consed) in ordine. Infine, abbiamo ottenuto [high,high,low,low]
.
Una versione modificata che rivela l'ordine di elaborazione ...
Siamo in grado di modificare il codice un po 'al fine di rendere il trattamento (consing) ordine più esplicito:
-module(prior).
-compile(export_all).
important() ->
receive
{Priority, Msg} when Priority > 10 ->
[{Priority, Msg} | important()] % <---- Edited
after 0 ->
normal()
end.
normal() ->
receive
{Priority, Msg} -> % <---- Edited
[{Priority, Msg} | normal()] % <---- Edited
after 0 ->
[]
end.
Run nella shell:
4> c(prior).
{ok, prior}
5> self() ! {15, high}, self() ! {7, low}, self() ! {1, low}, self() ! {17, high}.
{17,high}
6> prior:important().
[{15,high},{17,high},{7,low},{1,low}]
Non concatenato, consed. la concatenazione avviene quando si hanno due liste, 'L1' e' L2' e le si concatena: 'L1 ++ L2'. Consing è quando si ha un elemento 'E' e una lista' L' e quindi si forma la lista estesa '[E | L] '. –