【问题标题】:Testing truthiness in guards测试守卫的真实性
【发布时间】:2020-01-25 03:15:02
【问题描述】:

我可以使用守卫来测试参数是否为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风格的守卫吗?

def truthy?(term) do
  if term, do: "#{term} is truthy", else: "#{term} is falsey"
end

【问题讨论】:

    标签: elixir truthiness guard-clause


    【解决方案1】:

    根据official documentation for Guards

    Guard 以 when 关键字开头,后面是一个布尔表达式。

    所以守卫中的表达式必须是布尔表达式。

    elixir 中的真实性由 if/2 等宏定义。这些宏在守卫内部不可用,因此我们需要另一种方法将术语转换为布尔值。

    if/2的文档(和implementation)可以看出,真实性的定义是falsenil都是假的,其他都是真的。所以我们可以用它来实现我们的真实性守卫:

    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"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-06
      • 1970-01-01
      • 2019-09-14
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 2013-03-31
      相关资源
      最近更新 更多