关于使用“with”表达式解决我_only_问题的建议 - 访问成功结果
Advice for working around my _only_ problem with “with” expressions - accessing success results
考虑这段代码:
with {:a, first_result} <- {:a, List.first(["apple"])},
{:b, b} <- {:b, %{} |> to_string} do
{:ok, "happy path"}
else
{:a, _} -> {:error, "this will never be a problem"}
{:b, error} -> {:error, "Why can I not print #{first_result} here?"}
end
我通过反复试验得知此代码 不会 return
{:error, "Why can I not print apple here?"}
正如我最初对这种语法的预期。相反,编译器告诉我 first_result
没有在 else
块中定义。这是有道理的,因为“子句链”return是失败子句的错误结果。
所以我有两个问题:
- 实现预期结果的最佳方法是什么?我应该只使用两个单独的
case
表达式吗?
- 想象一下,如果第一个子句使用
Repo.insert
向数据库添加一些内容。 Ecto 是否知道它在 with
表达式中并在提交事务之前等待所有子句成功? :thinking: 这似乎不太可能。那么,为什么这个表达式不允许我们访问任何成功的结果?
似乎我在使用 with
时应该非常小心,因为如果我理解正确(我可能不理解),我可能会“部分成功”而看不到成功的结果。
欢迎任何建议和见解!我希望问题很清楚。
P.S。我已经阅读 https://hexdocs.pm/elixir/Kernel.SpecialForms.html#with/1。它只是说“链已中止”。
我的问题在这里得到了回答:
对用户 Bluejay 的支持。
用他们的话说,“这行得通”:
with {:a, first_result} <- {:a, List.first(["apple"])},
{:b, first_result, :something} <- {:b, first_result, :other_thing} do
{:ok, "happy path"}
else
{:a, _} -> {:error, "this will never be a problem"}
{:b, first_result, _} -> {:error, "Now I can print #{first_result} here"}
end
所以答案是使用先前子句结果中的变量来扩展匹配的子句元组。
考虑这段代码:
with {:a, first_result} <- {:a, List.first(["apple"])},
{:b, b} <- {:b, %{} |> to_string} do
{:ok, "happy path"}
else
{:a, _} -> {:error, "this will never be a problem"}
{:b, error} -> {:error, "Why can I not print #{first_result} here?"}
end
我通过反复试验得知此代码 不会 return
{:error, "Why can I not print apple here?"}
正如我最初对这种语法的预期。相反,编译器告诉我 first_result
没有在 else
块中定义。这是有道理的,因为“子句链”return是失败子句的错误结果。
所以我有两个问题:
- 实现预期结果的最佳方法是什么?我应该只使用两个单独的
case
表达式吗? - 想象一下,如果第一个子句使用
Repo.insert
向数据库添加一些内容。 Ecto 是否知道它在with
表达式中并在提交事务之前等待所有子句成功? :thinking: 这似乎不太可能。那么,为什么这个表达式不允许我们访问任何成功的结果?
似乎我在使用 with
时应该非常小心,因为如果我理解正确(我可能不理解),我可能会“部分成功”而看不到成功的结果。
欢迎任何建议和见解!我希望问题很清楚。
P.S。我已经阅读 https://hexdocs.pm/elixir/Kernel.SpecialForms.html#with/1。它只是说“链已中止”。
我的问题在这里得到了回答:
对用户 Bluejay 的支持。
用他们的话说,“这行得通”:
with {:a, first_result} <- {:a, List.first(["apple"])},
{:b, first_result, :something} <- {:b, first_result, :other_thing} do
{:ok, "happy path"}
else
{:a, _} -> {:error, "this will never be a problem"}
{:b, first_result, _} -> {:error, "Now I can print #{first_result} here"}
end
所以答案是使用先前子句结果中的变量来扩展匹配的子句元组。