Elixir 基于map的cond和模式匹配
在phoenix应用程序中,当用户提交特定表单时,lat和lng根据地址计算 lat和lng可以在未进行更改的情况下保存在changeset.data中,也可以在提交更改的情况下保存在changeset.changes中 我在变更集中对lat和lng执行其他操作,但我需要知道坐标在哪里。我想做的是:Elixir 基于map的cond和模式匹配,elixir,phoenix-framework,Elixir,Phoenix Framework,在phoenix应用程序中,当用户提交特定表单时,lat和lng根据地址计算 lat和lng可以在未进行更改的情况下保存在changeset.data中,也可以在提交更改的情况下保存在changeset.changes中 我在变更集中对lat和lng执行其他操作,但我需要知道坐标在哪里。我想做的是: cond do # Always use new coordinates if possible %{lat: lat, lng: lng} = changeset.changes -&g
cond do
# Always use new coordinates if possible
%{lat: lat, lng: lng} = changeset.changes ->
do_something(lat, lng)
%{lat: lat, lng: lng} = changeset.data ->
do_something(lat, lng)
true ->
do_nothing_and_return_the_changeset_as_is
end
当然,这不起作用,因为它不会在模式不匹配时返回true
或false
**(MatchError)右侧值不匹配:%{lat:any_value}
事实上,我做了一个很长的决定,看起来不太好,如果。。。。声明实现了这一点
有没有更好的长生不老药 您可以在以下函数中使用模式匹配:
...
# call do_something with the changeset
changset |> do_something()
#pattern match for lat,lng inside the changes
def do_something(%Ecto.Changeset{changes: {lat: lat, lng: lng}}) do
..
end
# pattern match for lat,lng inside data
def do_something(%Ecto_.Changeset{data: {lat: lat, lng: lng}}) do
..
end
# pattern match if no lat und lng are available !!! the order of the functions matters !!!
def do_something(%Ecto_Changeset{} = cs) do
cs
end
代码未经测试,可能包括类型,但我希望您能理解。您可以使用
大小写
匹配lat
和lng
内部更改
或数据
:
case changeset do
%{changes: %{lat: lat, lng: lng}} -> ...
%{data: %{lat: lat, lng: lng}} -> ...
_ -> ...
end
但是,有一个更好的方法:Ecto有一个get_field
函数,它处理从更改中获取字段值,自动返回到数据
lat = get_field(changeset, :lat)
lng = get_field(changeset, :lng)
if lat && lng do
...
else
...
end
在写下我的问题后,我发现这是我迄今为止没有测试过的选项。我现在正在尝试,我会回复你的!太好了,我没有意识到get\u field
,这似乎也是一个很酷的选择!