Elixir中的输入验证
我正在努力想出一个干净的方法来用Elixir进行输入验证 在OOP语言中,我会这样做:Elixir中的输入验证,elixir,Elixir,我正在努力想出一个干净的方法来用Elixir进行输入验证 在OOP语言中,我会这样做: def my_func(a, b): if !validate_a(a): raise ArgumentError if !validate_b(b): raise ArgumentError return "something" 我在长生不老药中能想到的最好的方法是: def my_func(a, b) do cond do not valid_a?(a) ->
def my_func(a, b):
if !validate_a(a):
raise ArgumentError
if !validate_b(b):
raise ArgumentError
return "something"
我在长生不老药中能想到的最好的方法是:
def my_func(a, b) do
cond do
not valid_a?(a) -> {:error, "a is invalid"}
not valid_b?(b) -> {:error, "b is invalid"}
:otherwise -> {:ok, "something"}
end
end
我知道我也可以在Elxir中引发异常,但我更喜欢针对返回类型的模式匹配,因为我的代码不会被try/rescue块弄乱
在长生不老药中有没有一种更好的模式可以做到这一点?一切都取决于验证后的内容以及您希望进行的验证类型 例如:若您只是验证a和b是整数,那个么您可以在函数的定义中使用保护子句
def my_func(a, b) when is_integer(a) and is_integer(b) do
# your code - validation passed
end
def my_func(_, _) do
# validation failed
end
在自定义验证方面,最好有单独的函数,您可以在主函数中使用它-您的代码更干净,更易于测试,因为它更好地隔离。在您的情况下,这个带有验证的cond可能在不同的函数中
在Phoenix控制器中处理验证时,您显然可以创建自己的验证,如果您可以像以前一样在Ruby on Rails控制器中使用验证,这非常方便。根据验证的复杂性和数据的外观,您也可以选择使用,即使您不打算存储数据 下面是一些非常简单的事情
defmodule Foo do
use Ecto.Schema
import Ecto.Changeset
schema "my_schema" do
field :name, :string
field :age, :integer
end
def changeset(struct, params) do
struct
|> cast(params, [:name, :age])
|> validate_required([:name, :age])
|> validate_number(:age, greater_than: 18)
end
end
一旦您运行changeset/2函数,您将得到一个具有有效?领域如果这是真的,它通过了您的所有验证。如果为false,它还会从变更集中的:errors键告诉您原因。我觉得您的代码很好。而不是:否则->对于最后一种情况,我看到大多数人使用true->。我也看到了。就个人而言,为了可读性,我更喜欢:else或:other。你能举例说明如何将我的cond块分解成不同的函数吗?在这种情况下:只需将其重命名为validate,在my_func中,我会在顶部调用validate。