Elixir中的输入验证

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) ->

我正在努力想出一个干净的方法来用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) -> {: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。