长生不老药尝试救援

Elixir try rescue

我不确定如何最好地做到这一点:

我有一个功能可以查找 IP 和 returns 它来自的国家/地区。

country = Geolix.lookup(remote_ip).country.registered_country.name

有时会失败,在这种情况下,定义了 none 个数组键。

在其他语言中,我可能会这样做:

try do
  country = Geolix.lookup(remote_ip).country.registered_country.name
rescue
  country = nil
end

我真的很难把语法弄好。这也感觉不太'clean';有没有更好的办法?

你不能用 try 宏来做这个。它不是为了控制流量而设计的。

我建议使用 Kernel.SpecialForms.with/1:

country =
  with %{country: country} <- Geolix.lookup(remote_ip),
       %{registered_country: rc} <- country,
       %{name: name} <- rc, do: name

Kernel.get_in/2 也可能有效:

get_in Geolix.lookup(remote_ip), ~w[country registered_country name]a

FWIW,这是正确的 Kernel.SpecialForms.try/1 语法:

country =
  try do
    Geolix.lookup(remote_ip).country.registered_country.name
  rescue
    _ -> nil
  end

@m3characters 的回答也很好

您还可以将 case ... do 与模式匹配一​​起使用,如果 case 的结果具有您需要的所有键,则它与第一个键匹配,您在其中提取名称,否则意味着你从 Geolix.lookup/1 得到的任何东西都不符合你想要的模式,你 return nil

country = 
       case Geolix.lookup(remote_ip) do
          %{country: %{registered_country: %{name: name}}} -> name
          _ -> nil
       end