Elixir 长生不老药和功能输入验证
我正在努力学习长生不老药(但主要是函数式编程) 我正在实现一个非常简单的GenServer,它基本上包装了一个条目列表。每个参数的最大条目数和最大大小(字节)受到限制(配置文件) 我知道这看起来很简单,但基本上我正在尝试找到一种优雅的功能性方法来实现这一点。我的头脑是程序化的,我总是在一个“嵌套的if-else-hell”中使用=操作符,就像它是C操作符一样Elixir 长生不老药和功能输入验证,elixir,Elixir,我正在努力学习长生不老药(但主要是函数式编程) 我正在实现一个非常简单的GenServer,它基本上包装了一个条目列表。每个参数的最大条目数和最大大小(字节)受到限制(配置文件) 我知道这看起来很简单,但基本上我正在尝试找到一种优雅的功能性方法来实现这一点。我的头脑是程序化的,我总是在一个“嵌套的if-else-hell”中使用=操作符,就像它是C操作符一样 thx我所知道的验证多个参数的最干净的方法是exto及其变更集。您可能想要实现非常类似的东西 创建包含值和验证错误的数据结构 使所有验证函
thx我所知道的验证多个参数的最干净的方法是
exto
及其变更集
。您可能想要实现非常类似的东西
changeset
,就像exto
一样changeset = %{data: {param1, param2, param3}, errors: []}
def validate_param(changeset, number) do
max_size = get_env(:app, :"param#{number}"
if elem(changeset.data, number-1) < max_size do
changeset
else
errors = [{:"param#{number}", elem(changeset.data, number-1)} | changeset.errors
%{ changeset | errors: errors}
end
end
validated_changeset =
changeset
|> validate_param(1)
|> validate_param(2)
|> validate_param(3)
case validated_changeset.errors do
[] -> {:reply, :ok, [changeset.data | list]}
errors -> {:reply, errors, list}
end
在引号内,您可以使用字符串插值,这样您就可以使用atom创建通用的validate_param
:“param{number}”
elem
函数的索引为零,因此我们需要从number
中减去1:elem(changeset.data,number-1)
如果没有错误,我们将返回变更集而不进行任何修改
错误将具有结构{field\u name,field\u value}
。将list
添加到变更集中,并创建一个验证函数来检查列表长度并附加正确的错误,应该很容易
您还可以使用列表在调用validate_param
3次时删除重复。foldl
:
List.foldl([1, 2, 3], changeset, fn(number, changeset) -> validate_number(changeset, number) end)
甚至更短:
List.foldl([1, 2, 3], changeset, &validate_number(&2, &1))
最重要的是函数的模式返回与第一个参数相同的类型。它可以很容易地进行管道处理,避免了许多嵌套的if
或case
语句
List.foldl([1, 2, 3], changeset, fn(number, changeset) -> validate_number(changeset, number) end)
List.foldl([1, 2, 3], changeset, &validate_number(&2, &1))