为什么在case语句中字符串“3”与范围('0'…'10')不匹配?

3z6pesqy  于 2021-07-13  发布在  Java
关注(0)|答案(2)|浏览(522)

当我尝试在case语句中匹配字符串“3”时,如果范围上升到“9”,则匹配,但不匹配“10”。
我猜这和三重等于运算符有关,但我不知道它为什么在这个范围内,但不匹配。
下面是一个irb运行,记录了两种情况:有效(使用“9”)和无效(使用“10”):

case '3'
 when ('0'...'9')
     puts "number is valid"
 else
   puts "number is not valid"
 end

输出: number is valid ```
case '3'
when ('0'...'10')
puts "number is valid"
else
puts "number is not valid"
end

输出: `number is not valid` 我用作预期结果参考的方法如下
Enumerable#include? `Enumerable#member?` 当转换为数组时,查看输出是什么是( `Enumerable#to_a` ).
“案例平等”的结果( `===` )接线员让我大吃一惊。

puts ('0'...'10').include?('3')

=> true

puts ('0'...'10').member?('3')

=> true

puts ('0'...'10') === '3'

=> false

puts ('0'...'10').to_a

=> ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

inkz8wg9

inkz8wg91#

范围使用 cover? 大小写相等。所以这是比较 '3' >= '0' && '3' < '10' 结果是 false 因为 '3' < '10' #=> false . 字符串根据字符值进行比较。
为了更好地理解,您可能希望将字符串视为字符数组:

['3'] <=> ['1', '0'] #=> 1 (first operand is larger than the second)

要解决此问题,请将案例输入转换为整数并使用整数范围:

case 3 # or variable.to_i
when 0...10
  puts 'number is valid'
else
  puts 'number is invalid'
end

这是因为整数的比较不是基于字符代码,而是基于实际值。 3 >= 0 && 3 < 10 结果 true .
或者,您可以明确地告诉何时使用 member? (或 include? )方法,而不是传递范围,而是传递方法。

case '3'
when ('0'...'10').method(:member?)
  puts 'number is valid'
else
  puts 'number is invalid'
end
ee7vknir

ee7vknir2#

=== 说它相当于 cover? ,后者的文档说明

begin <= obj < end

所以,在你的情况下,我们

'0' <= '3' < '10'

以及 <= 以及 < 在字符串上使用字典顺序进行比较,因此比较为false。
另一方面,我们必须做更多的挖掘来找出什么 member? / include? 实际上是这样的(两者是等价的)。如果我们查看源代码,就会发现两者都调用了一个名为 range_include_internal 对于行为不同于 cover? . 后者要求 rb_str_include_range_p 它有更多的特殊情况,包括你的数字情况。

相关问题