比较 case 语句和 if 语句中的类时出现意外结果

Unexpected results when comparing classes in case statement vs an if statment

提问人:Mendoza 提问时间:1/16/2018 最后编辑:Mendoza 更新时间:4/13/2023 访问量:234

问:

因此,我正在编写一个模块函数,将“falsey”和“truthy”值转换为true和false。为此,我使用了一个 case 表达式,据我所知,它基本上只是一个大的 elseif 语句,它使用 === 函数,其中 === 运算符用于比较集合。从 Ruby 文档中,我真正能找到的 == 和 === 之间的唯一区别是 === 可以被覆盖以比较类的后代。我也明白一切都是 ruby 中的方法调用,所以我们不能假设相等/包含方法是可交换的。

当使用 case 语句按类排序时,我会猜测 == 和 === 的功能是相同的,但我发现当按类排序时,他们的 case 语句永远不会将我的输入放入正确的“bin”。在这一点上,我切换到使用 == 并且它确实有效,所以我想知道为什么会这样,因为我正在比较类,我认为这实际上是“苹果对苹果”的比较。

module FirstTry
  def self.to_boolean(uncertain_value, to_integer: false)
    case uncertain_value.class
    when String
      value = ActiveRecord::Type::Boolean.new.cast(uncertain_value)
      return 1 if to_integer == true && value == true
      return 0 if to_integer == true && value == false
      return boolean_value
    when TrueClass
      return 1 if to_integer == true
      return true
    when FalseClass
      return 0 if to_integer == true
      return false
    when NilClass
      return 0 if to_integer == true
      return false
    end
    # I did not originally include this part of the code in the question
    raise 'Conversion Failed: No rules for converting that type of input into a boolean.'
  end
end

module SecondTry
  def self.to_boolean(uncertain_value, to_integer: false)
    if uncertain_value.class == String
      boolean_value = ActiveRecord::Type::Boolean.new.cast(uncertain_value)
      return 1 if to_integer == true && boolean_value == true
      return 0 if to_integer == true && boolean_value == false
      return boolean_value
    elsif uncertain_value.class == TrueClass
      return 1 if to_integer == true
      return true
    elsif uncertain_value.class == FalseClass
      return 0 if to_integer == true
      return false
    elsif uncertain_value.class == NilClass
      return 0 if to_integer == true
      return false
    end
    # I did not originally include this part of the code in the question
    raise 'Conversion Failed: No rules for converting that type of input into a boolean.'
  end
end
Ruby-on-Rails 红宝石 平等

评论

2赞 Jörg W Mittag 1/16/2018
你问的是某物的类是否是一个字符串。显然,事实并非如此。某物的类是一个类,而不是一个字符串。
2赞 mu is too short 1/16/2018
顺便说一句,你所做的工作比你需要的要多得多。 负责字符串、布尔值......对你来说,所以你不需要所有这些分支,只是逻辑应该就足够了。ActiveRecord::Type::Boolean.new.castnilvalue = ActiveRecord::Type::Boolean.new.cast(uncertain_value)to_integer
1赞 Cary Swoveland 1/16/2018
return在每个子句的最后一行中不需要(例如,可以并且应该简单地写成)。此外,您可以使用三元表达式来代替 ,例如 。如果你只关心这是真实的,那就把它简化为。return falsefalsereturn 0 if to_integer == true; return falseto_integer == true ? 0 : falseto_integerto_integer ? 0 : false

答:

3赞 Martin Svalin 1/16/2018 #1

在 Ruby 中的表达式中,三等号在引擎盖下被称为。我们发现能够表达如下内容很方便:===case

case object
when String
  "object is an instance of String!"
when Enumerable
  "wow, object is actually a bunch of objects!"
end

当然,这很方便,除非您实际持有类,而不是类的实例。但在您的示例中,您在 case 表达式中调用对象。只需挂断电话,您的箱子就会被放入正确的箱子里。:)#class

0赞 Alex Dias 4/13/2023 #2

您可以在案例陈述中进行比较.class.to_s

评论

0赞 Narfanator 4/20/2023
仅供参考:“社区”机器人标记了这个答案。我敢打赌它不明白 Ruby 是多么简洁明了!