鲁比“当”关键字在 case 语句中不使用 ==。它有什么用?

发布于 2024-09-24 10:03:49 字数 349 浏览 3 评论 0原文

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

u = User.new
# => #<User:0x00000100a1e948>

x = u.class
# => User

x == User
# => true

case x
when User
  puts "constant"
when "User"
  puts "string"
else
  puts "nothing?"
end
# => nothing?

x == User returns true, but case x statement does not run the block associated with User. What's happening here?

u = User.new
# => #<User:0x00000100a1e948>

x = u.class
# => User

x == User
# => true

case x
when User
  puts "constant"
when "User"
  puts "string"
else
  puts "nothing?"
end
# => nothing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

人间☆小暴躁 2024-10-01 10:03:49

大小写比较使用 === 而不是 ==。对于许多对象, ===== 的行为是相同的,请参阅 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 comparisons use === rather than ==. For many objects the behaviour of === and == is the same, see Numeric and String:

5 == 5 #=> true
5 === 5 #=> true

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

But for other kinds of object === can mean many things, entirely depending on the receiver.

For the case of classes, === tests whether an object is an instance of that class:

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

For Range it checks whether an object falls in that range:

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

For Procs, === actually invokes that Proc:

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

For other objects, check their definition of === to uncover their behaviour. It's not always obvious, but they usually make some kind of sense..

Here is an example putting it all together:

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  

See this link for more info: http://www.aimred.com/news/developers/2008/08/14/unlocking_the_power_of_case_equality_proc/

随梦而飞# 2024-10-01 10:03:49

在 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
=> #<User:0xb7a90cd8>
irb(main):004:0> User === u.class
=> false
irb(main):005:0> User === u
=> true

In case statement , the comparison is done using === operator.

So your code is translated to following:

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

Different class define === in different way:

The Class class define === so that it tests whether the righthand operand (x)is an instance of the class named by the lefthand operand (User). So , It is not surprise that User === x will be evaluated as false. Instead, User === u (u = User.new) is true.

irb(main):001:0> class User
irb(main):002:1> end
=> nil
irb(main):003:0> u = User.new
=> #<User:0xb7a90cd8>
irb(main):004:0> User === u.class
=> false
irb(main):005:0> User === u
=> true
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文