如何正确地格式化长复合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,只要行结束and
或or
或或是或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
这种方法的主要缺点是速度慢。 如果使用and
和or
运算符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