Ruby中case语句的类比较为何失败?
问题根源与解决方法
核心原因
Ruby 的 case 语句里,when 条件使用的是**=== 运算符**,而类对象(比如 Question)的默认 === 逻辑是:判断右侧对象是否是该类的实例,而非判断两个类对象是否相等。
举个直观的例子:
klass = Question # == 判断的是两个变量是否指向同一个类对象,结果为 true klass == Question # => true # === 判断的是 klass 是否是 Question 的实例,显然不成立(klass 是 Class 的实例) Question === klass # => false
所以你写 case klass; when Question; ...; end 时,实际执行的是 Question === klass,结果为 false,自然匹配不上。
解决方法
方法1:用 Lambda 做相等判断
when 可以接收 Proc/Lambda 对象,会自动调用 call 并传入 case 的目标值,直接写相等判断逻辑即可:
case klass when ->(k) { k == Question } # 这里写匹配成功后的逻辑 end
方法2:比较类的字符串表示
就是你已经尝试成功的方法,把类转为字符串后再匹配:
case klass.to_s when Question.to_s # 这里写匹配成功后的逻辑 end
方法3:用 equal? 判断对象同一性
如果需要严格判断是否是同一个类对象(和 == 对于类的效果一致,除非类重写了 == 方法):
case klass when ->(k) { k.equal?(Question) } # 这里写匹配成功后的逻辑 end
如果需要匹配多个类,也可以扩展 Lambda 的判断逻辑:
case klass when ->(k) { [Question, Answer, Comment].include?(k) } # 匹配任意指定类时执行的逻辑 end
内容的提问来源于stack exchange,提问作者Jared Menard
相关产品推荐
相关产品推荐

