这是一个包含测试的代码示例,其中我有一个函数检查传入的值是否在允许的值集中,如果不是,则会引发异常,但如果传入的值为零或一个空字符串,它只返回 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/