我经常看到这种情况:
if ([CONSTANT_1, CONSTANT_2, CONSTANT_3].contains? var && a_boolean) #...
而不是:
if ((var == CONSTANT_1 || var == CONSTANT_2 || var == CONSTANT_3) var && a_boolean) #...
我明白第一个条件更优雅,但是创建一个数组只是为了检查条件是不好的,还是使用的资源可以忽略不计?
前一种模式确实会产生更多的内存压力和 CPU 开销,因为每次运行此代码时都必须分配该数组。
也就是说,这不一定是问题,除非它是一个特别热的代码路径。如果这是一个在某个地方的库深处经常调用的方法,我可能会选择第二个版本以避免额外的分配,但对于调用率相对较低的业务代码,我认为第一个版本的可读性是可以接受的。
第二个版本(像大多数复杂的条件一样)容易出错。很容易忘记是否需要括号或布尔逻辑的工作原理。"变量是这些值之一吗,如果是,这是其他事情吗?"的模式可能特别棘手,因此简化当然是有意义的。
但是,我认为数组类不包括contains?
,是吗?在我的测试中,我使用了include?
:
CONSTANT_1 = 1
CONSTANT_2 = 2
CONSTANT_3 = 3.14
a_boolean = true
var = 3.14
puts "true" if [CONSTANT_1, CONSTANT_2, CONSTANT_3].include?(var) && a_boolean
请注意,var
周围的括号是必需的,以便include?
不会搜索var && a_boolean
而不仅仅是var
。
我看到这个成语的唯一真正的问题是,让var
排在第一位会更好一些。在SQL中,你可以写一些类似的东西:
var in (CONSTANT_1, CONSTANT_2, CONSTANT_3) and a_boolean
这似乎读起来更自然一点。
如果您真的担心效率并且多次执行此测试,那么最好设置一个哈希:
constant_test = {}
[CONSTANT_1, CONSTANT_2, CONSTANT_3].each do |k|
constant_test[k] = true
end
puts "true" if constant_test[var] && a_boolean
这样做的优点是每次测试时都是哈希查找而不是循环。(另请参阅:此答案。
理想情况下,您不会看到其中任何一个。 相反,你会使用这样的东西,通过将条件分解为小块功能,会更习惯和更可测试。
我意识到这个例子if
你正在使用的并不完全相同,但它足够接近,可以表明我的意思。
class Thing
def initialize(var)
@var = var
end
def a_method
return 'yes' if has_constaints? && boolean?
'no'
end
private
def has_constaints?
@var == CONSTANT_1 || @var == CONSTANT_2 || @var == CONSTANT_3
end
def boolean?
@var && a_boolean
end
end