如何在我的代码中实现多个if条件,如下所示
person = %Person{}
if x.name == "Test" do
person = %{person | name: "Test"}
end
if x.age == 50 do
person = %{person | age: 50}
end
这里“x”是我尝试验证数据然后相应地更新person结构的另一个对象。 我已经编写了上面的代码,但得到了以下警告
变量“person”不安全,因为它已被设置在以下之一: case,cond,receive,if,and,or,&&,||。请明确退回 变量值而不是。例如:
case integer do 1 -> atom = :one 2 -> atom = :two end
应该写成
atom = case integer do 1 -> :one 2 -> :two end
答案 0 :(得分:3)
当您匹配多个子句来验证字段时,我会组合验证这些片段的函数,如下所示:
defmodule PersonChecker do
def validate(x, person) do
person
|> validate_name(x)
|> validate_age(x)
end
defp validate_name(person, %{name: name}) when name == "Test" do
%{person | name: "Test"}
end
defp validate_name(person, _x), do: person
defp validate_age(person, %{age: age}) when age == 50 do
%{person | age: 50}
end
defp validate_age(_x, person), do: person
end
如果您想使用case
而不是多个validate_name
函数,它将如下所示:
defp validate_name(person, x) do
case x.name do
"Test" -> %{person | name: "Test"}
_ -> person
end
end
顺便说一句,根据您的使用情况,使用x
删除您不想要的字段可能会更容易,然后使用x
将struct(Person, x)
转换为结构<ns1:ATT_ADDR_VAL_REQ xmlns="http://lsr.att.com/preorder">
<ns2:ADDR_VAL_REQ xmlns="http://lsr.att.com/obf/tML/UOM">
函数。
答案 1 :(得分:2)
您无法重新绑定块内的变量。如错误消息所示,请将其设置为显式:
person = %Person{}
person = if x.name == "Test", do: %{person | name: "Test"}, else: person
person = if x.age == 50, do: %{person | age: 50}, else: person
即使变量是不可变的,Elixir也允许重新绑定,但是如果不允许它会更容易理解(比如在Erlang中)。在这种情况下,您必须编写如下内容:
person = %Person{}
person_with_name = if x.name == "Test", do: %{person | name: "Test"}, else: person
person_with_name_and_age = if x.age == 50, do: %{person_with_name | age: 50}, else: person_with_name
答案 2 :(得分:2)
Elixir中的所有东西都是不可改变的。我建议你阅读Elixir中重新绑定变量的this great writing by José Valim。
您所使用的功能主要是减少字段列表中的struct
,这就是为什么我可能会选择Enum.reduce/3
:
defmodule Person, do: defstruct ~w|foo name age|a
x = [name: true, age: false] # flags
~w|name age|a
|> Enum.zip(['Test', 50])
|> Enum.reduce(%Person{foo: :bar}, fn {field, value}, acc ->
if x[field], do: %{acc | field => value}, else: acc
end)
#⇒ %Person{age: nil, foo: :bar, name: 'Test'}