我经常看到这种情况:
if ([CONSTANT_1, CONSTANT_2, CONSTANT_3].contains? var && a_boolean) #...
而不是:
if ((var == CONSTANT_1 || var == CONSTANT_2 || var == CONSTANT_3) var && a_boolean) #...
我明白第一个条件更优雅,但创建一个数组只是为了检查一个条件是坏的还是使用的资源是否可以忽略不计?
答案 0 :(得分:0)
前一种模式确实会产生更大的内存压力和CPU开销,因为每次运行此代码时都必须分配该数组。
尽管如此,除非它是一个特别热门的代码路径,否则这不一定是个问题。如果这是一个在某个地方经常深入调用的方法,我可能选择第二个版本来避免额外的分配,但对于具有相对较低的通话率的业务代码,我认为第一个的可读性是可以接受的
答案 1 :(得分:0)
第二个版本(像最复杂的条件一样)容易出错。很容易忘记你是否需要括号或布尔逻辑是如何工作的。 "的模式是这些值中的变量之一,如果是这样,那么另一个是真的吗?"可能特别棘手,所以简化是有道理的。
但是,我不认为Array类包含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
这样做的好处是每次测试时都是哈希查找而不是循环。 (另见:this answer。)
答案 2 :(得分:0)
理想情况下,你不会看到其中任何一个。相反,你可以使用类似这样的东西,通过将条件分解成小块功能来更加惯用和更可测试。
我意识到这个例子与你使用的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