如何使 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#curry
和 Proc#===
。
【讨论】:
【参考方案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 案例语句使用等于 (==) 而不是三等号 (===)的主要内容,如果未能解决你的问题,请参考以下文章