接下来与if。在一个.each循环中?
我有一个文本处理的东西,我在Ruby中做。 基本上,我必须实现一个简单的状态机(一个字符后视)。
我的代码目前看起来像这样:
text.each{ |c| ... ... ... ... if @state!=:some_state next end #processing stuff for if in :some_state mode ... ... ... ... ... }
这是对的吗? 或者它应该像下面这样实现:
text.each{ |c| ... ... ... ... if @state==:some_state #processing stuff for if in :some_state mode ... ... ... ... ... end }
有正确的方式还是只是偏好? 哪一个与做事的“ruby方式”更加融合?
与@DigitalRoss完全一致,如果在评估某些条件后存在复杂的代码,我看到有人使用next
next if @state!=:some_state # some long complicated code
另一方面,如果有一个简单的操作需要在某些条件的基础上进行,那么我更愿意
if @state == :some_state #call_a_method_to_do_something end OR call_a_method if @state == :some_state
话虽如此,编写冗长的复杂代码却是不好的做法。 如果您的代码干净且设计良好,那么您将永远不必在代码中使用next
。
我认为你给出的例子并没有真正捕捉到next
做出改变的情况。 考虑一下代码中有多个“next-points”的情况:
text.each do |c| next if @state == :state1 ... next if @state == :state2 ... next if @state == :state3 ... end
并将其与if-variant进行比较:
text.each do |c| unless @state == :state1 ... unless @state == :state2 ... unless @state == :state3 ... end end end end
虽然第一种可以被一些纯粹主义者视为意大利面风格,但恕我直言,它比后者更具可读性。
这是第二种方式
一些思想流派反对各种语言的东西,如下next
, retry
, continue
和break
,因为他们只是在不受尊重的goto
声明的方向上有点过分。
这些语句确实有它们的用例,但总的来说,当一个结构化的向下指向的结构将完成相同的事情时,故意“spaghettify”代码是一个坏主意。 现在,如果条件要求跳过整个循环体,那么我可能更喜欢使用next
。
我会去:
text.each{ |c| ... ... Generic state processing ... case @state when :state_1 then code when :state_2 then code end }
但如果它与第一个样本一样(意味着只有1个状态需要额外的处理)
text.each{ |c| ... ... Generic state processing ... next unless @state == :state_1 ... ... Code that process states other than :state_1 }
更进一步而不是点击实例变量,如果对象是否处于我们需要的状态,它听起来更好听:
def processed? @state == :state_1 end ... next unless processed? # sounds like natural language... ...
进一步推理,我认为一个内衬就像’下一个除非处理?’ 只有当同一个缩进级别的代码不超过10行时才是好的,否则我宁愿做另一个,所以缩进将帮助我乍看之下发生了什么