实例化数组是一种不好的编程习惯吗?



我经常看到这种情况:

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

最新更新