Elixir 1.2'de "with" anahtar sözcüğünü eklediler, ancak bunun ne için olduğu tamamen açık değil.Elixir'deki "with" anahtar kelimesi nasıl kullanılır ve ne için kullanılır?
Nasıl ve hangi durumlarda kullanabilirim? önce 1.2 Elixir sürümlerinde
Elixir 1.2'de "with" anahtar sözcüğünü eklediler, ancak bunun ne için olduğu tamamen açık değil.Elixir'deki "with" anahtar kelimesi nasıl kullanılır ve ne için kullanılır?
Nasıl ve hangi durumlarda kullanabilirim? önce 1.2 Elixir sürümlerinde
bir boru hattı işlevleri kullanırken, bir monad kütüphane veya iç içe durum ifadeleri kullanması gerekir ya (özel işlevleri kullanarak refactored, ancak yine de uzun olmakla sona ereceğini) . with/1, bu sorunu çözmek için farklı bir yol sağlar. Aynı kod with
kullanılarak
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
Ve:
with {:ok, binary} <- File.read(path),
{:ok, data} <- :beam_lib.chunks(binary, :abstract_code),
do: {:ok, wrap(data)}
İşte
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
işlevlerini kullanmak için refactored aynı şeydir: Burada
original proposal bir örnektir Bu,
with
yalnızca tutulacağı için çalışır Değer, soldaki desene uyuyorsa zincirleme. Değilse, zincir iptal edilir ve eşleşen olmayan ilk sonuç döndürülür. herhangi deseni ile kullanılabilir ile değil, sadece
{:ok, foo}
ve
{:error, reason}
(her ne nedenle
with/1
çağrı Bu fazlalaştı
{:error, :enoent}.
dönecektir bu {:ok, binary}
eşleşmiyor - Örneğin dosya daha sonra File.read(path)
{:error, :enoent}
dönecektir yoksa çok yaygın bir kullanım durumudur).
doktor diyor Ayrıca, "çıplak ifadeleri" zincir edebilirsiniz:
with {:ok, binary} <- File.read(path),
header = parse_header(binary),
{:ok, data} <- :beam_lib.chunks(header, :abstract_code),
do: {:ok, wrap(data)}
değişken header
sadece with
deyimi içinde satışa sunulacak. Daha fazla bilgi için https://gist.github.com/josevalim/8130b19eb62706e1ab37
with
ifadesinden when
muhafazasını kullanabilirsiniz. E.g,
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 , %{}})
Gerçekten de "sürümüyle" çok daha iyi görünüyor. Bu çok kullanışlı. – diogovk
Ben bence 'defp read_chunks' sadece okunmalıdır '': beam_lib.chunks (binary,: abstract_code) '(yani, ilk' {: ok, 'olmadan) – Grandpa
Ben ok_jose gibi hissediyorum (https: // github. com/vic/ok_jose) çok daha temiz görünüyor (adın dışında). Bunun yerine kullanmamak için herhangi bir sebep var mı? – Johannes