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


68

如果我有一个复杂的if语句,我不想​​仅仅出于美学目的而溢出,那么将其分解的最简洁的方式是什么,因为在这种情况下coffeescript会将return解释为语句的主体?

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

如果not bar第一子句中有可能(如第二子句所示),则该引用bar.data将导致错误...
Trevor Burnham

Answers:


86

如果该行以运算符结尾,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

感谢你的回答。我没有意识到这是一个很棒的规则,因为操作员是Coffeescript中换行的关键。
伊凡

2
如果您不想缩进ifstatmenet的主体“甚至更多”,则可以使用then,从与相同的级别开始if。恕我直言,它更具可读性。
Dmytro Shevchenko 2012年

压痕说明;主体不必比的非第一行更缩进if。正确语法的唯一规则是(据我所知):1)主体的缩进不能与和的第一行或最后一行相同;if以及2)主体或主体的任何行都if不能比的缩进少。的第一行if。还要注意,您可以在不同的非第一if行上使用不同的缩进。
LoPoBo

我通常if用2个标签缩进非第一行(以便使它们既不在之后也不在if),并在正文中缩进1个标签。
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 < cCoffeeScript中的合法性一样。当然,重复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

2
如果某些谓词的计算成本很高并且如果在单个表达式中使用更早的谓词已经可能得出该语句的结果该怎么办?
HalilÖzgür2015年

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

抱歉,我必须对此投票。问题是“打破[一个漫长的陈述”的最粗俗的方式”,这个答案是非常不相关的。
Ardee Aram
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.