then else delete atom erlang erl

else - Recepción selectiva en Erlang



list in erlang (3)

ellos están ubicados aquí

[Msg | important()]

este important() es una función por lo que tiene un valor de retorno, mientras ejecuta esto en REPL, imprimirá el valor de retorno de la función. Este valor es efecto de [Head | Tail] [Head | Tail] list building from import()

important() aquí es una función regular :)

¿Es útil?

Así que comencé a aprender Erlang y estoy un poco confundido con este trozo de código.

-module(prior). -compile(export_all). important() -> receive { Priority, Msg } when Priority > 10 -> [Msg | important()] after 0 -> normal() end. normal() -> receive { _, Msg } -> [Msg | normal()] after 0 -> [] end.

Estoy llamando al código usando.

10> self() ! {15, high}, self() ! {7, low}, self() ! {1, low}, self() ! {17, high}. {17,high} 11> prior:important(). [high,high,low,low]

Entiendo que este código pasará primero por todos los mensajes de prioridad alta y luego por los de prioridad baja. Estoy confundido en cuanto a cómo el valor de retorno es [alto, alto, bajo, bajo], ya que no veo dónde están concatenados juntos.


Todas las funciones de Erlang siempre devuelven un valor. La función important/0 recibirá un mensaje de alta prioridad y luego se llamará recursivamente en la expresión [Msg | important()] [Msg | important()] que construye una lista que contiene la última Msg y todos los demás mensajes que recibirá important/0 . Es esta lista la que se devuelve desde important/0 . Cuando no hay más mensajes de alta prioridad, entonces important/0 llamará a normal/0 para leer todos los mensajes restantes. Los mensajes que normal/0 lee volverán como una lista de la misma manera important/0 . Esto se devolverá a important/0 que luego lo devolverá en la misma lista que devolvió sus mensajes.

Tenga en cuenta que una vez que se ha llamado a normal/0 no habrá un manejo especial de los mensajes de alta prioridad ya que nunca se llamará de nuevo a 0. También important/0 realmente solo procesará los mensajes de alta prioridad que ya están en la cola, ya que una vez que no puede encontrar más, llama a normal/0 .

El valor 0 tiempo de espera es especial, ya que agota el tiempo de manera inmediata, pero garantiza que primero busque en toda la cola de mensajes los mensajes coincidentes.


Cómo se construye el valor de retorno final ...

Cuando [Msg | important()] [Msg | important()] se devuelve por primera vez, se determina la forma del valor de retorno final. La única preocupación es que aún no conocemos todos los detalles del valor de retorno final. Entonces lo important() en el [Msg | important()] [Msg | important()] continuará siendo evaluado. La siguiente es una ilustración de cómo se construye el valor de retorno final [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

Cómo funciona el código ...

En función important/0 , after 0 simplemente significa "No espero a que lleguen los mensajes"; si hay algún mensaje en mi buzón, lo miraré; si no hay ninguno, continuaré (ejecutar normal() ) en lugar de esperar allí. En el buzón, ya hay {15, alto}, {7, bajo}, {1, bajo}, {17, alto} sentado allí. En Erlang, los mensajes en el buzón no están en cola en orden de orden de llegada. La cláusula de receive puede ser exigente. Escanea todos los mensajes en el buzón y "selecciona" los que desea. En nuestro caso, {15, alto} y {17, alto} se eligen primero según {Priority, Msg} when Priority > 10 . Después de eso, la función normal/0 hace cargo. Y {7, low}, {1, low} se procesan (consed) en orden. Finalmente, obtuvimos [high,high,low,low] .

Una versión modificada que revela el orden de procesamiento ...

Podemos modificar el código un poco para hacer que el orden de procesamiento (consing) sea más explícito:

-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.

Ejecútelo en el 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}]