elixir - 在 Elixir 中如何对 nil 或空白字符串进行模式匹配?

标签 elixir

这是一个包含测试的代码示例,其中我有一个函数检查传入的值是否在允许的值集中,如果不是,则会引发异常,但如果传入的值为零或一个空字符串,它只返回 false。这里的想法是任何类型的空白值都意味着没有值(value)。如果存在与有效值之一不匹配的非空值,那么我们确实希望引发异常,因为该值无效。还想象这个值来自命令行参数或 Phoenix 请求参数,我们无法控制输入值只是 nil,我们必须检查空值、nil、空字符串或仅包含字符串的所有排列。空格。

ExUnit.start()

defmodule ValidColor do
  @valid_colors MapSet.new(~w[red green blue])

  def valid?(color) do
    cond do
      blank?(color) -> false
      MapSet.member?(@valid_colors, color) -> true
      true -> raise "invalid color"
    end
  end

  defp blank?(value) do
    case value do
      nil -> true
      v when is_binary(v) -> v =~ ~r/\A\s*\z/
      _ -> false
    end
  end
end

defmodule ValidColorTest do
  use ExUnit.Case, async: true

  test "nil" do
    refute ValidColor.valid?(nil)
  end

  test "empty string" do
    refute ValidColor.valid?("")
  end

  test "string with only blank characters" do
    refute ValidColor.valid?("     ")
  end

  test "invalid color" do
    assert_raise RuntimeError, "invalid color", fn ->
      ValidColor.valid?("yellow")
    end
  end

  test "valid color" do
    assert ValidColor.valid?("red")
  end
end

这似乎是 blank? 辅助函数有用的情况,正如我在本示例中所做的那样。好像有a sentiment among Elixir programmers that this type of helper method is unnecessary and can be done with pattern matching .

如何仅使用模式匹配而不使用 blank? 辅助函数来实现这样的函数?

最佳答案

虽然这里给出的所有答案在某种程度上都是正确的,但它们在语义上并不完美。您想要的实际上是将 nil 视为空字符串并拒绝它。简单点:

defp blank?(str_or_nil),
  do: "" == str_or_nil |> to_string() |> String.trim()

请注意,与目前给出的其他解决方案不同,此解决方案适用于所有空格,在 UTF-8 规范中定义为空格。

关于elixir - 在 Elixir 中如何对 nil 或空白字符串进行模式匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52482825/

相关文章:

linux - 如何在 .service 脚本中使用环境变量

mysql - 如何通过 Ecto 向 MySQL 提供索引提示

elixir - 为什么通过字符列表重新创建字符串时会得到不同的字符串

Elixir 与函数名的使用

postgresql - 将当前时间的默认值设置为 Ecto 迁移中的日期时间列

xml - 如何使用 mix 包发送非 elixir 文件?

heroku - Phoenix + Ueberauth + 谷歌 + Heroku : internal server error

elixir - 将嵌套元组转换为 elixir 中的列表

elixir - 如何根据两列对ecto中的表进行排序

elixir - 匿名函数不能混合子句