2011-07-08 24 views
68

如果我有一个复杂的if语句,我不想​​仅仅出于美学目的溢出,自coffeescript将解释返回值以来最奇怪的方式是什么?在这种情况下声明的正文?如何正确地格式化长复合if语句在Coffeescript

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

如果'未bar'是第一子句中的可能性(作为第二条款建议),则参考'bar.data'将会引起错误... –

回答

84

的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 

或任何其他的换行方案,只要线andoris==not或一些这样的运营商

至于压痕结束时,可以缩进您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 

什么你不能做的是:

# 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 
+0

感谢您的回答。这是一个很好的规则,我没有意识到运营商是打破Coffeescript的关键。 – Evan

+2

如果你不想缩进'如果'statmenet的身体“甚至更多”,你可以使用'then',从'if'开始。它更可读,恕我直言。 –

+0

关于压痕的注意事项;身体不必比'if'的非第一行更加缩进。正确语法的唯一规则是(据我所知):1)body不能和'if'的第一行或最后一行有相同的缩进,2)body和'if'可以比'if'的第一行缩进更少。另请注意,您可以在不同的非第一个“if”行上使用不同的缩进。 – LoPoBo

3

这会改变你的代码的意思是有些,但可能会有一些使用:

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

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

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

if foo and有点不雅;如果没有机会fooundefined,则可以丢弃它。

2

像其他任何语言一样,首先没有它们。给不同部分命名,分别对待他们。要么通过声明谓词,要么通过创建几个布尔变量。

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 
+1

如果某些谓词计算起来很昂贵,而且如果在单个表达式中使用早期谓词,则可能会得出该语句的结果呢? –

2

逃脱换行符看起来最可读的对我说:

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

当很多低级别的样板时,你应该抽象增长水平。

最好的解决方案是:

  • 使用良好的命名变量和函数

  • 逻辑规则的if/else报表

一个逻辑规则是:

(非A和非B)==没有(A或B)

的第一种方式。变量:

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运营商的功能和替代变量与功能,我们会得到更好的性能:

  • C = A和B

如果A是假的操作and难道不呼叫

  • C = A或B

如果A是真实的运营商or难道不呼叫

第二种方式。功能:

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 
+0

对不起,我不得不冷静下来。问题是“最简单的方式来打破[长时间的陈述]”,这个答案是非常不相关的。 –