首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby中的负条件语句

Ruby中的负条件语句
EN

Stack Overflow用户
提问于 2016-10-21 18:43:16
回答 3查看 3.4K关注 0票数 4

似乎每当看到负条件语句时,RubyMine IDE都会发出警告。我想知道为什么使用否定的条件语句是不好的?这纯粹是因为可读性吗?

例如,在此代码中:

代码语言:javascript
复制
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? strandif !(dna_strucutre.include?)有什么不同?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-10-21 19:28:49

因为Ruby不仅有if,而且有unless,所以只要结果代码是清晰的,就鼓励您使用它。也就是说,您应该转换如下内容:

代码语言:javascript
复制
if (!string.empty?)
  # ...
end

变成这样的东西:

代码语言:javascript
复制
unless (string.empty?)
  # ...
end

这是有例外的,比如当你有这样的情况时:

代码语言:javascript
复制
if (!string.empty?)
  # ... when not empty
else
  # ... when empty (when not not empty)
end

天真的方法是将其转换为unless,但这会产生三重负值。您已经在这里处理一个double了,只有当字符串不为空,或者可以说不包含任何内容时,else子句才会发生。

取而代之的是这样做:

代码语言:javascript
复制
if (string.empty?)
  # ... when empty
else
  # ... when not empty
end

这里使用的方法有很多问题,但最严重的是,每次调用方法时,都会在方法内声明一个常数数组。因为这一点永远不会改变,所以在类级别的顶部使它成为一个常量。至少:

代码语言:javascript
复制
class Complement
  DNA_STRUCTURE = %w[ C G A T ]
end

更好的做法是使用映射表来表示配对:

代码语言:javascript
复制
COMPLEMENT = {
  'C' => 'G',
  'G' => 'C',
  'T' => 'A',
  'A' => 'U'
}.freeze

现在看看您要“反转”给定字符串的特定问题,您真正想要的工具是字符串本身上的tr,这是一种优化的方法,用于处理字符之间有1:1映射的密码器。

您的整个功能将折叠到以下内容:

代码语言:javascript
复制
def self.of_dna(strand)
  strand.tr('CGTA', 'GCAU')
end

现在,如果您想做一个快速测试以确保您实际上正在处理一个有效的序列:

代码语言:javascript
复制
def self.of_dna(strand)
  return '' unless (strand.match(/\A[CGTA]*\z/))

  strand.tr('CGTA', 'GCAU')
end

这里还有其他一些坏习惯,比如在字符串更好地执行特定任务时创建数组来保存单个字符。c = ''c << 'G'将比数组版本更有效,特别是考虑到数组将包含N个字符串,每个字符串都带有一些开销,并且需要在最后使用join创建另一个字符串。在使用Ruby时,请尽量减少计算所需的对象数量,无论是临时的还是其他的。用较少的“垃圾”通常更快。

票数 7
EN

Stack Overflow用户

发布于 2016-10-21 18:49:09

后一种形式没有什么问题,但考虑到在ruby中我们有unless,我们应该使用它,当我们只有一个分支,它是可取的,就像在这种情况下。

总之,这是完全一样的。

票数 1
EN

Stack Overflow用户

发布于 2016-10-21 18:55:00

我想是马匹上的课..。我和一些优秀的开发人员合作过,他们的第一语言不是英语,他们觉得If ! (如果不是)更容易理解。

但是Ruby指南https://github.com/bbatsov/ruby-style-guide特别喜欢unless而不是if !,但对于与else一起使用的unless却不以为然。

最后,最好用单行重写,并附带条件.

代码语言:javascript
复制
    return '' unless dna_structure.include? strand 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40183479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档