如何使 ruby​​ 案例语句使用等于 (==) 而不是三等号 (===)

Posted

技术标签:

【中文标题】如何使 ruby​​ 案例语句使用等于 (==) 而不是三等号 (===)【英文标题】:How to make a ruby case statement use equals to (==) rather than threequals (===) 【发布时间】:2019-06-24 21:34:20 【问题描述】:

Ruby 的 case 语句默认使用 ===。有没有办法让它改用“等于”(即==)?

这样做的动机是因为我有 5 个 if 语句可以很好地被 switch 替换,但得知这一点我有点惊讶

datatype = "string".class
if datatype == String
puts "This will print"
end

不一样

case datatype
when String
puts "This will NOT print"
end

【问题讨论】:

ref你能帮忙吗? Ruby 的 case 语句使用 ===。它不会“默认使用”。 我遇到了this(看起来case 在课程方面的行为也绊倒了其他一些人 【参考方案1】:

您不能让case 不使用===,但您可以重新定义=== 以使用==

class Class
  alias === ==
end

case datatype
when String
  puts "This will print"
end
# >> This will print

或者,您可以为此创建一个特定的类。

class MetaClass
  def initialize klass
    @klass = klass
  end

  def ===instance
    instance == @klass
  end
end

def meta klass
  MetaClass.new(klass)
end

case datatype
when meta(String)
  puts "This will print"
end
# >> This will print

【讨论】:

重新定义 === 有危险吗?它可以用于其他方法(我可能不知道)吗?我是否有可能通过重新定义它来破坏其他方法? === 除了在case 语句中很少使用,所以它并不那么危险。但是,如果您担心它与代码的其他部分交互,请考虑将别名更改为 Refinement 中的方法定义,并在 Refinement 范围内使用相关的 case 语句。 这有点像here,但很好地放在这里+1【参考方案2】:

对于@sawa 的建议,这将是一种更简洁、更简洁 (IMSO) 的方法。使用 λ 而不是包装类。

META = ->(type, receiver)  receiver == type 

case "string".class
when META.curry[Integer] then puts 'integer'  
when META.curry[String] then puts 'string'  
end  

#⇒ "string"

此解决方案在后台使用 Proc#curryProc#===

【讨论】:

【参考方案3】:

类似于 Aleksei Matiushkin 的回答,但没有咖喱:

is_class = ->(klass)  ->(item)  item == klass  

10.times do
  case ['abc', 123].sample.class
  when is_class[String]
    puts "it's the abc"
  when is_class[Integer]
    puts "easy as 123"
  end
end

这里发生了什么?

第一行定义了一个返回另一个过程的过程 proc[x]proc.call(x) 相同 proc.===(x)proc.call(x) 相同 is_class[Integer] 返回一个执行 |val| val == Integer 的过程 ..由于=== ==> call,它被case的参数作为参数调用。

最大的缺点是它会产生很多 procs 并且看起来很奇怪。

当然,你的问题的明显解决方案是不做datatype = "string".class

datatype = "string"
case datatype
when String
puts "This will print"
end

【讨论】:

【参考方案4】:

你也可以使用case语句的显式形式

datatype = test_object.class

case
when datatype == String
  puts "It's a string"
when datatype < Numeric
  puts "It's a number"
end

请注意,表达式 datatype 将适用于所有数字类型。

【讨论】:

以上是关于如何使 ruby​​ 案例语句使用等于 (==) 而不是三等号 (===)的主要内容,如果未能解决你的问题,请参考以下文章

如何使用PG Ruby Gem有条件地回滚事务

在案例语句 SQL 中使用数组

如何使用css使高度等于宽度[重复]

如何根据 if-then 决策树设置 ruby​​ 变量

如何使下拉表单在 Ruby On Rails 中工作

Oracle SQL:案例语句