Elixir 什么是“;获取或插入”;?

Elixir 什么是“;获取或插入”;?,elixir,Elixir,我有一些代码,通过在ETS中查找用户,或者创建一个结构,将该值存储在ETS中并返回新创建的用户,来计算用户 user = if user = Data.lookup(phone) do user else user = %User{phone: phone} Data.insert({phone, user}) user end 然而,在我看来,它不是最好的代码,我也不知道如何重构它。在长生不老药中,什么是一种惯用的方法呢?我肯定会使用模式匹配: def get_user(p

我有一些代码,通过在ETS中查找用户,或者创建一个结构,将该值存储在ETS中并返回新创建的用户,来计算用户

user = if user = Data.lookup(phone) do
  user
else 
  user = %User{phone: phone}
  Data.insert({phone, user})
  user
end

然而,在我看来,它不是最好的代码,我也不知道如何重构它。在长生不老药中,什么是一种惯用的方法呢?

我肯定会使用模式匹配:

def get_user(phone, nil) do
  user = %User{phone: phone} 
  Data.insert({phone, user})
  user
end
def get_user(phone, %User{} = user), do: user
然后,您可以从代码中调用:

user = get_user(phone, Data.lookup(phone))

尽管@Daniel的答案完全正确,我很可能会在制作中使用它,但为了多样性,这里有另一种方法

可以在
数据上实现行为,将所有实现细节隐藏在那里,并在需要时在后台透明地创建用户


此外,非布尔严格析取也可以:

defp创建用户(电话)do
用户=%user{phone:phone}
Data.insert({phone,user})
使用者
结束
用户=数据。查找(电话)| |创建用户(电话)

标题可以进一步改进:在任何情况下,将其细化为相关将确保/允许此类问题保留有用性。出于好奇,我想知道用例是什么,因为如果您能够仅从
电话创建新用户
,您实际上可以返回
%user{phone:phone}
无需查找,或者如果关键是确保ETS有钥匙,您可以直接调用。我假设您的实际用例有更多的字段?而且,这可能不是问题,只是提到:get if not insert方法不是原子的,在并发运行时可能导致竞争条件。我认为如果您使用的是
:set
,并且没有假定
插入总是成功的,那么这应该没问题。我对ETS不太熟悉,但找不到任何原子函数来执行这种原子的“开箱即用”获取或创建…@sabiwara,是的,这个结构有更多的字段,而不仅仅是一个
phone
字段。谢谢你让我知道可能的比赛情况。目前的假设是,不同的用户会有不同的流程,所以我认为我们在这里不会有问题(可能是著名的最后世界:)