测试守卫的真实性
Testing truthiness in guards
我可以使用守卫来测试参数是否为 true
:
defmodule Truth do
def true?(term) when term, do: "#{term} is true"
def true?(term), do: "#{term} is not true"
end
这对于布尔值按预期工作:
Truth.true?(true)
#=> "true is true"
Truth.true?(false)
#=> "false is not true"
但无法验证其真实性:
Truth.true?(1)
#=> "1 is not true"
是否可以测试守卫的真实性?比如下面的函数可以用上面true?/1
的风格使用guards来写吗?
def truthy?(term) do
if term, do: "#{term} is truthy", else: "#{term} is falsey"
end
根据 official documentation for Guards:
Guards start with the when
keyword, which is followed by a boolean expression.
所以guards中的表达式必须是布尔表达式
长生不老药的真实性由 if/2
等宏定义。这些宏在守卫内部不可用,因此我们需要另一种方法将术语转换为布尔值。
从if/2
的文档(和implementation)可以看出,真实的定义是false
和nil
都是假的,其他都是真.所以我们可以用它来实现真实性守卫:
defmodule Truth do
defguard is_falsey(term) when term in [false, nil]
defguard is_truthy(term) when not is_falsey(term)
def truthy?(foo) when is_truthy(foo), do: "#{foo} is truthy"
def truthy?(foo), do: "#{foo} is falsey"
end
这会按预期工作:
Truth.truthy?(true)
#=> "true is truthy"
Truth.truthy?(1)
#=> "1 is truthy"
Truth.truthy?(false)
#=> "false is falsey"
Truth.truthy?(nil)
#=> " is falsey"
我可以使用守卫来测试参数是否为 true
:
defmodule Truth do
def true?(term) when term, do: "#{term} is true"
def true?(term), do: "#{term} is not true"
end
这对于布尔值按预期工作:
Truth.true?(true)
#=> "true is true"
Truth.true?(false)
#=> "false is not true"
但无法验证其真实性:
Truth.true?(1)
#=> "1 is not true"
是否可以测试守卫的真实性?比如下面的函数可以用上面true?/1
的风格使用guards来写吗?
def truthy?(term) do
if term, do: "#{term} is truthy", else: "#{term} is falsey"
end
根据 official documentation for Guards:
Guards start with the
when
keyword, which is followed by a boolean expression.
所以guards中的表达式必须是布尔表达式
长生不老药的真实性由 if/2
等宏定义。这些宏在守卫内部不可用,因此我们需要另一种方法将术语转换为布尔值。
从if/2
的文档(和implementation)可以看出,真实的定义是false
和nil
都是假的,其他都是真.所以我们可以用它来实现真实性守卫:
defmodule Truth do
defguard is_falsey(term) when term in [false, nil]
defguard is_truthy(term) when not is_falsey(term)
def truthy?(foo) when is_truthy(foo), do: "#{foo} is truthy"
def truthy?(foo), do: "#{foo} is falsey"
end
这会按预期工作:
Truth.truthy?(true)
#=> "true is truthy"
Truth.truthy?(1)
#=> "1 is truthy"
Truth.truthy?(false)
#=> "false is falsey"
Truth.truthy?(nil)
#=> " is falsey"