如何正确地格式化长复合if语句在Coffeescript

如果我有一个复杂的陈述,我不想仅仅为了审美的目的而溢出,那么自从coffeescript将解释回报作为本案的陈述主体之后,最有可能的方法是什么?

if (foo is bar.data.stuff and foo isnt bar.data.otherstuff) or (not foo and not bar) awesome sauce else lame sauce 

如果行以操作符结束,CoffeeScript将不会将下一行解释为语句的主体,所以这是正确的:

 # OK! if a and not b c() 

它编译为

 if (a && !b) { c(); } 

所以你的if可以被格式化为

 # OK! if (foo is bar.data.stuff and foo isnt bar.data.otherstuff) or (not foo and not bar) awesome sauce else lame sauce 

或任何其他换行scheme,只要行结束andor或或是或not或某些此类运营商

至于缩进,只要主体更加缩进,就可以缩进你的非第一行:

 # OK! if (foo is bar.data.stuff and foo isnt bar.data.otherstuff) or (not foo and not bar) awesome sauce else lame sauce 

你不能做的是这样的:

 # BAD if (foo #doesn't end on operator! is bar.data.stuff and foo isnt bar.data.otherstuff) or (not foo and not bar) awesome sauce else lame sauce 

这有点改变你的代码的含义,但可能有一些用处:

 return lame sauce unless foo and bar if foo is bar.data.stuff isnt bar.data.otherstuff awesome sauce else lame sauce 

注意is...isnt链,这是合法的,正如在CoffeeScript中a < b < c是合法的。 当然,重复lame sauce是不幸的,你可能不想马上return 。 另一种方法是用浸泡来写

 data = bar?.data if foo and foo is data?.stuff isnt data?.otherstuff awesome sauce else lame sauce 

if foo and有点不雅; 如果foo没有被undefined话,你可以丢弃它。

像任何其他语言一样,没有他们摆在首位。 给不同部分的名字分别对待他们。 要么通过声明谓词,要么通过创build几个布尔variables。

 bar.isBaz = -> @data.stuff != @data.otherstuff bar.isAwsome = (foo) -> @isBaz() && @data.stuff == foo if not bar? or bar.isAwesome foo awesome sauce else lame sauce 

逃离linebreak看起来对我来说是最可读的:

 if (foo is bar.data.stuff and foo isnt bar.data.otherstuff) \ or (not foo and not bar) awesome sauce else lame sauce 

当出现很多低级别的样板时,应该提高抽象层次

最好的解决scheme是:

  • 使用好的命名variables和函数

  • if / else语句中的逻辑规则

逻辑规则之一是:

(不是A而不是B)==不(A或B)

第一种方法。 variables:

 isStuff = foo is bar.data.stuff isntOtherStuff = foo isnt bar.data.otherstuff isStuffNotOtherStuff = isStuff and isntOtherStuff bothFalse = not (foo or bar) if isStuffNotOtherStuff or bothFalse awesome sauce else lame sauce 

这种方法的主要缺点是速度慢。 如果使用andor运算符function并用函数replacevariables,我们将获得更好的性能:

  • C = A和B

如果A是虚假的运营商, and 不会打电话

  • C = A或B

如果A是真实的运营商or 打电话

第二种方法。 function:

 isStuff = -> foo is bar.data.stuff isntOtherStuff = -> foo isnt bar.data.otherstuff isStuffNotOtherStuff = -> do isStuff and do isntOtherStuff bothFalse = -> not (foo or bar) if do isStuffNotOtherStuff or do bothFalse awesome sauce else lame sauce