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

如何正确格式化Coffeescript中的长复合if语句,coffeescript,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 如果下一行以运算符结尾,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

如果下一行以运算符结尾,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
或任何其他断线方案,只要线路以
结束,即为
=
或某类运算符

至于缩进,您可以缩进
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

这在一定程度上改变了代码的含义,但可能有一些用处:

return lame sauce unless foo and bar
if foo is bar.data.stuff isnt bar.data.otherstuff
  awesome sauce
else
  lame sauce
请注意,
是…不是
链,这是合法的,正如
a
在CoffeeScript中是合法的一样。当然,
lame-sause
的重复是不幸的,您可能不想立即返回。另一种方法是使用浸液进行书写

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

如果foo和
有点不雅;如果
foo
不可能像任何其他语言一样是
未定义的

的,那么您可以放弃它,因为首先不需要它们。给不同的部分命名,并分别处理。要么声明谓词,要么只创建几个布尔变量

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

转义换行符对我来说最容易理解:

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

当大量低级样板文件出现时,您应该提高抽象的级别

最佳解决方案是:

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

  • 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
这种方法的主要缺点是速度慢。如果我们使用
运算符功能并用函数替换变量,我们将获得更好的性能:

  • C=A和B
如果
A
为假,操作员
将不会调用

  • C=A或B
如果
A
为真,操作员
不会调用

第二种方式。功能:

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

如果第一条中有可能出现
not bar
(如第二条所示),则参考
bar.data
将导致错误…感谢您的回答。这是一条我没有意识到的关于操作符是Coffeescript中换行的关键的伟大规则。如果您不想缩进
If
statmenet的主体“甚至更多”,您可以使用
then
,从与
If
相同的级别开始。它更具可读性,我想。缩进上的注释;正文不必比
if
的非第一行缩进更多。正确语法的唯一规则是(据我所知):1)正文不能与
if
的第一行或最后一行具有相同的缩进;2)正文或
if
的任何一行的缩进都不能小于
if
的第一行。还请注意,您可以在不同的非第一个
if
行上有不同的缩进。我通常使用两个制表符缩进非第一个
if
行(以便使它们既不在
if
之后也不在
内部)主体有1个标签。如果一些谓词的计算成本很高,而早期的谓词如果在单个表达式中使用,则可能会得出语句的结果,那该怎么办?对不起,我不得不对此投反对票。这个问题是“打破(一个冗长的if声明)的最合乎犹太教义的方式”,而这个答案与此毫不相关。