似乎每当看到负条件语句时,RubyMine IDE都会发出警告。我想知道为什么使用否定的条件语句是不好的?这纯粹是因为可读性吗?
例如,在此代码中:
class Complement
def self.of_dna dna_strand
dna_array = dna_strand.chars
dna_complement = ['']
dna_structure = ['C', 'G', 'T', 'A']
dna_array.each do |strand|
unless dna_structure.include? strand
return ''
end
case strand
when "C"
dna_complement << "G"
when "G"
dna_complement << "C"
when "T"
dna_complement << "A"
when "A"
dna_complement << "U"
end
end
dna_complement.join('')
end
end我想知道在这种情况下,unless dna_structure.include? strand和if !(dna_strucutre.include?)有什么不同?
发布于 2016-10-21 19:28:49
因为Ruby不仅有if,而且有unless,所以只要结果代码是清晰的,就鼓励您使用它。也就是说,您应该转换如下内容:
if (!string.empty?)
# ...
end变成这样的东西:
unless (string.empty?)
# ...
end这是有例外的,比如当你有这样的情况时:
if (!string.empty?)
# ... when not empty
else
# ... when empty (when not not empty)
end天真的方法是将其转换为unless,但这会产生三重负值。您已经在这里处理一个double了,只有当字符串不为空,或者可以说不包含任何内容时,else子句才会发生。
取而代之的是这样做:
if (string.empty?)
# ... when empty
else
# ... when not empty
end这里使用的方法有很多问题,但最严重的是,每次调用方法时,都会在方法内声明一个常数数组。因为这一点永远不会改变,所以在类级别的顶部使它成为一个常量。至少:
class Complement
DNA_STRUCTURE = %w[ C G A T ]
end更好的做法是使用映射表来表示配对:
COMPLEMENT = {
'C' => 'G',
'G' => 'C',
'T' => 'A',
'A' => 'U'
}.freeze现在看看您要“反转”给定字符串的特定问题,您真正想要的工具是字符串本身上的tr,这是一种优化的方法,用于处理字符之间有1:1映射的密码器。
您的整个功能将折叠到以下内容:
def self.of_dna(strand)
strand.tr('CGTA', 'GCAU')
end现在,如果您想做一个快速测试以确保您实际上正在处理一个有效的序列:
def self.of_dna(strand)
return '' unless (strand.match(/\A[CGTA]*\z/))
strand.tr('CGTA', 'GCAU')
end这里还有其他一些坏习惯,比如在字符串更好地执行特定任务时创建数组来保存单个字符。c = ''和c << 'G'将比数组版本更有效,特别是考虑到数组将包含N个字符串,每个字符串都带有一些开销,并且需要在最后使用join创建另一个字符串。在使用Ruby时,请尽量减少计算所需的对象数量,无论是临时的还是其他的。用较少的“垃圾”通常更快。
发布于 2016-10-21 18:49:09
后一种形式没有什么问题,但考虑到在ruby中我们有unless,我们应该使用它,当我们只有一个分支,它是可取的,就像在这种情况下。
总之,这是完全一样的。
发布于 2016-10-21 18:55:00
我想是马匹上的课..。我和一些优秀的开发人员合作过,他们的第一语言不是英语,他们觉得If ! (如果不是)更容易理解。
但是Ruby指南https://github.com/bbatsov/ruby-style-guide特别喜欢unless而不是if !,但对于与else一起使用的unless却不以为然。
最后,最好用单行重写,并附带条件.
return '' unless dna_structure.include? strand https://stackoverflow.com/questions/40183479
复制相似问题