In Elixier 1.2 haben sie das Stichwort "mit", aber es ist mir nicht ganz klar, wofür es ist.Wie benutzt man das Schlüsselwort "mit" in Elixir und wozu dient es?
Wie und in welcher Situation würde ich es verwenden?
In Elixier 1.2 haben sie das Stichwort "mit", aber es ist mir nicht ganz klar, wofür es ist.Wie benutzt man das Schlüsselwort "mit" in Elixir und wozu dient es?
Wie und in welcher Situation würde ich es verwenden?
In Versionen von Elixir vor 1.2, wenn Funktionen in einer Pipeline verwenden, würden Sie haben entweder eine Monade Bibliothek oder Nest Case-Anweisungen verwenden (die mit privaten Funktionen Refactoring werden könnte, aber nach wie vor würden seine ausführlichen am Ende) . with/1 ermöglicht eine andere Möglichkeit, dieses Problem zu lösen. Hier
ist ein Beispiel aus der original proposal:
case File.read(path) do
{:ok, binary} ->
case :beam_lib.chunks(binary, :abstract_code) do
{:ok, data} ->
{:ok, wrap(data)}
error ->
error
end
error ->
error
end
Hier ist die gleiche Sache Refactoring-Funktionen verwenden:
path
|> File.read()
|> read_chunks()
|> wrap()
defp read_chunks({:ok, binary}) do
{:ok, :beam_lib.chunks(binary, :abstract_code)}
end
defp read_chunks(error), do: error
defp wrap({:ok, data}) do
{:ok, wrap(data)}
end
defp wrap(error), do: error
Und der gleiche Code with
mit:
with {:ok, binary} <- File.read(path),
{:ok, data} <- :beam_lib.chunks(binary, :abstract_code),
do: {:ok, wrap(data)}
Dies funktioniert, weil with
nur behalten wird Verkettung, wenn der Wert mit dem Muster auf der linken Seite übereinstimmt. Wenn nicht, wird die Kette abgebrochen und das erste nicht übereinstimmende Ergebnis wird zurückgegeben. Zum Beispiel, wenn die Datei nicht existiert dann File.read(path)
kehrt {:error, :enoent}
- das ist nicht {:ok, binary}
überein, so dass der with/1
Anruf kehrt {:error, :enoent}.
Es ist erwähnenswert, dass mit mit jedem Muster verwendet wird, nicht nur {:ok, foo}
und {:error, reason}
(obwohl es ist ein sehr häufiger Anwendungsfall).
Sie können auch die Kette "bare Ausdrücke", wie der Doc sagt:
with {:ok, binary} <- File.read(path),
header = parse_header(binary),
{:ok, data} <- :beam_lib.chunks(header, :abstract_code),
do: {:ok, wrap(data)}
Die Variable header
nur innerhalb der with
Anweisung zur Verfügung stehen wird. Weitere Informationen unter https://gist.github.com/josevalim/8130b19eb62706e1ab37
Eine Sache zu erwähnen, können Sie when
Schutz in with
Anweisung verwenden. Zum Beispiel
defmodule Test do
def test(res) do
with {:ok, decode_res} when is_map(decode_res) <- res
do
IO.inspect "ok"
else
decode_res when is_map(decode_res) -> IO.inspect decode_res
_ ->
IO.inspect "error"
end
end
end
Test.test({:ok , nil})
Test.test({:ok , 12})
Test.test({:ok , %{}})
In der Tat sieht die "mit Version" viel besser aus. Dies ist sehr nützlich. – diogovk
Ich denke, der Körper von 'defp read_chunks' sollte nur lesen ': beam_lib.chunks (binary,: abstract_code)' (dh ohne die anfängliche '{: ok,') – Grandpa
Ich fühle mich wie ok_jose (https: // github. com/vic/ok_jose) sieht viel sauberer aus (abgesehen von dem Namen). Gibt es einen Grund, das nicht stattdessen zu verwenden? – Johannes