有什么区别
case item.class
when MyClass
# do something here
when Array
# do something different here
when String
# do a third thing
end
Run Code Online (Sandbox Code Playgroud)
和
case item.class
when MyClass.class
# do something here
when Array.class
# do something different here
when String.class
# do a third thing
end
Run Code Online (Sandbox Code Playgroud)
出于某种原因,这些中的第一个有时会起作用而第二个起作用,而其他时候,第二个起作用,而第一个起作用.为什么?哪一个是"正确"的方式呢?
我刚刚注意到Array不会覆盖三重等号方法===,有时也称为大小写等式方法.
x = 2
case x
when [1, 2, 3] then "match"
else "no match"
end # => "no match"
Run Code Online (Sandbox Code Playgroud)
而范围运算符确实:
x = 2
case x
when 1..3 then "match"
else "no match"
end # => "match"
Run Code Online (Sandbox Code Playgroud)
但是,您可以为数组执行解决方法:
x = 2
case x
when *[1, 2, 3] then "match"
else "no match"
end # => "match"
Run Code Online (Sandbox Code Playgroud)
知道为什么会这样吗?
是因为它更有可能x成为一个实际的数组而不是一个范围,并且数组重写===意味着普通的相等不匹配?
# This is ok, because x being 1..3 is a very unlikely event
# But if …Run Code Online (Sandbox Code Playgroud) case "Hello".class
when Integer
print "A"
when String
print "B"
else
print "C"
end
Run Code Online (Sandbox Code Playgroud)
为什么我得到"C"?期待"B",因为如果你评价"String".class你确实得到了String.
如果我有klass可能(或可能不是)的实例Class,我如何检查klasscase语句样式中的给定类以查看它是哪个类的子类?
例如,假设klass恰好是Fixnum.当我检查klass时Integer,Float......,我希望它匹配Integer.这段代码:
case klass
when Integer ...
when Float ...
else ...
end
Run Code Online (Sandbox Code Playgroud)
将无法工作,因为它将检查是否klass是类的实例.我想检查是否klass是类的子类(或者本身就是该类).
这是迄今为止我能做的最好的,但我觉得这可能是一种矫枉过正而且效率不高:
class ClassMatcher
def initialize klass; @klass = klass end
def === other; other.kind_of?(Class) and other <= @klass end
end
class Class
def matcher; ClassMatcher.new(self) end
end
klass = Fixnum
case klass
when Integer.matcher then puts "It is a subclass …Run Code Online (Sandbox Code Playgroud)