【问题标题】:Why does "foo".class === String return false?为什么“foo”.class === String 返回 false?
【发布时间】:2015-11-30 23:43:25
【问题描述】:

当这没有按预期工作时,我开始好奇:

var = "foo"
case var.class
when String
  puts "bar"
else
  puts "baz"
=> "baz"

我知道 case 语句使用的是 ===,但我不明白 === 做了什么。文档说...

大小写相等 – 对于类 Object,实际上与调用 #== 相同, 但通常会被后代覆盖以提供有意义的 case 语句中的语义。

http://ruby-doc.org/core-2.2.3/Object.html#method-i-3D-3D-3D

这是否意味着 Class(或其模块之一)中的 === 会覆盖 Object 中的 ===?我很困惑。

【问题讨论】:

    标签: ruby string boolean equality


    【解决方案1】:

    ===Class 对象(更一般地,Module objects)覆盖,表示“右侧是左侧的实例”。

    例如:

    >> String === ""
    => true
    >> Class === String
    => true
    

    这是不直观的,但这是真的。但是,它确实使您尝试做的事情变得更短:

    var = "foo"
    case var
    when String
      puts "bar"
    else
      puts "baz"
    end
    # outputs "bar", since String === "foo"
    

    这就是您的尝试失败的原因:Ruby 计算 String === String,这是错误的,因为 String 类本身不是字符串。

    【讨论】:

      【解决方案2】:

      您在这里与case equality 打交道。在这里,它被后代覆盖以提供有意义的语义。在这种情况下,Module 会覆盖它。

      Case Equality — 如果对象是模块的实例或模块的后代之一,则返回 true。对模块的使用有限,但可用于 case 语句按类对对象进行分类。

      在模块中,=== 的作用类似于 Ruby 的 is_a? 方法。

      在您的情况下,它返回 false,因为 "Foo".class 不是字符串类的实例。

      "Foo".class.is_a?(String)
      => false
      

      【讨论】:

        【解决方案3】:

        这与如何为类实现大小写等价运算符=== 有关。使用对象,而不是 object.class

        var = "foo"
        case var
        when String
          puts "bar"
        else
          puts "baz"
        => "bar"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-11-15
          • 2012-06-12
          • 2023-04-10
          • 1970-01-01
          • 2015-09-26
          • 1970-01-01
          • 2019-12-29
          • 2013-09-18
          相关资源
          最近更新 更多