Sono nuovo in Erlang e sto provando a programmare un programma con problemi di buffer limitato. Funziona quasi, tranne che per assicurarsi che i produttori non siano troppo avanti e sovrascrivano i dati non consumati. Per gestire questo, ho deciso di provare a inserire protezioni sulla mia funzione buffer() in modo che potessi avere una versione senza ricezione usata quando il buffer è pieno, una versione senza invio usata quando il buffer è vuoto e una normale versione per il resto del tempo.Impossibile chiamare la funzione nella funzione di protezione
Il mio problema è che la protezione per la versione senza ricevitore richiede che conosca la dimensione della matrice che rappresenta il buffer, che richiede una chiamata a array:size/1
. Apparentemente, Erlang non consente invocazioni di funzioni nelle guardie, il che impedisce che funzioni. C'è un modo per ovviare a questo senza cambiare la dichiarazione della funzione per il mio attore buffer?
%% buffer: array num num
%% A process that holds the shared buffer for the producers and consumers
buffer(Buf, NextWrite, NextRead) when NextWrite == NextRead ->
io:format(" * ~w, ~w, ~w~n", [array:to_list(Buf), NextRead, NextWrite]),
receive
{enqueue, Reply_Pid, Num} ->
io:format("~w: > ~w~n", [Reply_Pid, Num]),
buffer(array:set(NextWrite rem array:size(Buf), Num, Buf), NextWrite + 1, NextRead);
finish ->
io:format("finished printing~n")
end;
buffer(Buf, NextWrite, NextRead) when (NextWrite - NextRead) == array:size(Buf) ->
io:format(" * ~w, ~w, ~w~n", [array:to_list(Buf), NextRead, NextWrite]),
receive
{dequeue, Reply_Pid} ->
io:format("~w: < ~w~n", [Reply_Pid, array:get(NextRead rem array:size(Buf), Buf)]),
Reply_Pid ! {reply, array:get(NextRead rem array:size(Buf), Buf)},
buffer(Buf, NextWrite, NextRead + 1);
finish ->
io:format("finished printing~n")
end;
buffer(Buf, NextWrite, NextRead) ->
io:format(" * ~w, ~w, ~w~n", [array:to_list(Buf), NextRead, NextWrite]),
receive
{dequeue, Reply_Pid} ->
io:format("~w: < ~w~n", [Reply_Pid, array:get(NextRead rem array:size(Buf), Buf)]),
Reply_Pid ! {reply, array:get(NextRead rem array:size(Buf), Buf)},
buffer(Buf, NextWrite, NextRead + 1);
{enqueue, Reply_Pid, Num} ->
io:format("~w: > ~w~n", [Reply_Pid, Num]),
buffer(array:set(NextWrite rem array:size(Buf), Num, Buf), NextWrite + 1, NextRead);
finish ->
io:format("finished printing~n")
end.
Questo è bello, semplice e facilmente comprensibile. Grazie. –
Ciao @Geoff, conosci un modo per confrontare due stringhe come guardia ?. es. - function when string: equals (string1, string2) -> 1. –
@DenisWeerasiri Sono abbastanza sicuro che 'string: equals/2' sia lo stesso di' == 'quindi puoi semplicemente usarlo nella guardia . –