Ruby` when’关键字在case语句中不使用==。 它有什么用?

x == User返回true ,但case x语句不运行与User关联的块。 这里发生了什么事?

 u = User.new # => # x = u.class # => User x == User # => true case x when User puts "constant" when "User" puts "string" else puts "nothing?" end # => nothing? 

案例比较使用===而不是== 。 对于许多对象, =====的行为是相同的,请参阅NumericString

 5 == 5 #=> true 5 === 5 #=> true "hello" == "hello" #=> true "hello" === "hello" #=> true 

但对于其他类型的对象===可能意味着许多事情,完全取决于接收者。

对于类的情况, ===测试对象是否是该类的实例:

 Class === Class.new #=> true. 

对于Range,它会检查对象是否属于该范围:

 (5..10) === 6 #=> true 

对于Procs, ===实际调用Proc

 multiple_of_10 = proc { |n| (n % 10) == 0 } multiple_of_10 === 20 #=> true (equivalent to multiple_of_10.call(20)) 

对于其他对象,请检查其对===的定义以揭示其行为。 它并不总是很明显,但它们通常会产生某种意义。

以下是将所有内容放在一起的示例:

 case number when 1 puts "One" when 2..9 puts "Between two and nine" when multiple_of_10 puts "A multiple of ten" when String puts "Not a number" end 

有关详细信息,请参阅此链接: http : //www.aimred.com/news/developers/2008/08/14/unlocking_the_power_of_case_equality_proc/

在case语句中,使用===运算符完成比较。

所以你的代码被翻译成以下内容:

 case x when User === x puts "Constant" when "User" === x puts "string" else puts "nothing" end 

不同的类以不同的方式定义===

Class类定义===以便它测试右手操作数( x )是否是由左操作数( User )命名的类的实例。 因此, User === x将被评估为false并不奇怪。 相反, User === u (u = User.new)为true

 irb(main):001:0> class User irb(main):002:1> end => nil irb(main):003:0> u = User.new => # irb(main):004:0> User === u.class => false irb(main):005:0> User === u => true