ruby - 使用 `===`(包含运算符)比较类

标签 ruby class types switch-statement comparison-operators

TypeOfClass === TypeOfClassfalse 的事实让我觉得有悖常理。在下面的代码中,即使 field.class 是同一个类,它的计算结果也是 false:

case field.class
when Fixnum, Float
  field + other_field
when Date, DateTime, Time
  field
else
  puts 'WAT?'
end

我这样做了:

Fixnum === Fixnum # => false
Class === Class   # => true

我找到了 another thread :

Integer === 3 # => true
Fixnum === 3  # => true
3.class       # => Fixnum

我找不到这种语言设计的原因。语言设计者在处理这种行为时在想什么?

我认为这与 another thread 中提供的答案相关.假设 Numeric === Integer 并非不自然,因为 Integer 是一种更具体的 Numeric 类型。但是,它不是:

Numeric === Integer #=> false

我认为 case 语句或 === 需要谨慎。如果这个运算符是什么 we think it is ,那么,一个Numeric应该是一个Numeric,一个Integer应该是一个Numeric,等等。

有没有人解释为什么这个特性没有扩展到类?如果比较的类是该类祖先的成员,返回 true 似乎很容易。

根据下面提交的答案,代码最初是对 Time 进行分类(由 ActiveSupport:CoreExtensions::Integer::TimeActiveSupport:CoreExtensions::Float::Time 扩展):

Timeframe = Struct.new(:from, :to) do
  def end_date
    case self.to
    when Fixnum, Float
      self.from + self.to
    when Date, DateTime, Time
      self.to
    else  
      raise('InvalidType')
    end
  end
end

在控制台中,我得到:

tf = Timeframe.new(Time.now, 5.months)
# => #<struct Timeframe from=Tue Dec 10 11:34:34 -0500 2013, to=5 months>
tf.end_date
# => RuntimeError: InvalidType
#  from timeframe.rb:89:in `end_date'

最佳答案

我真的没有看到这里的问题。对于类,大小写相等运算符会询问左侧参数是否是该类(或任何子类)的实例。所以 Fixnum === Fixnum 实际上是在问:“Fixnum 类本身是 Fixnum 的子类吗?”不,不是。

Class 本身是一个类吗? Class === Class,是的。

运算符(operator)的意思是你不需要去寻找类(class)。在开始时使用没有 .class 方法的 case 语句有什么问题?

case field
when Fixnum, Float
  field + other_field
when Date, DateTime, Time
  field
else
  puts 'WAT?'
end

如果您有一个更复杂的示例,您可以编写自己的 lambda 来简化 case 语句:

field_is_number =  -> x {[Fixnum, Float].include? x.class}
field_is_time   =  -> x {[Date, DateTime, Time].include? x.class}

case field.class
  when field_is_number
    field + other_field
  when field_is_time
    field
  else
    puts 'WAT?'
end

关于ruby - 使用 `===`(包含运算符)比较类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20498449/

相关文章:

php - 每个 LI foreach 的替代类(class)

apache-flex - 在弹出文本输入控件上设置焦点

ruby - Mbox 中的数据转换为 JSON 或 CSV?

Java 问题 : Is it a method?

c++ - 这些对象初始化之间有什么区别?

javascript - 将 !!someVar 替换为 Boolean(someVar) 是否 100% 正确?

c++ - 混淆 double 和 float 数据类型

ruby - 我们可以在 Ruby 中并行运行多线程吗?

ruby - Ruby 如何评估数学表达式的真/假?

ruby - 我怎样才能在 Ruby 中做标准偏差?