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

Posted

技术标签:

【中文标题】如何正确格式化 Coffeescript 中的长复合 if 语句【英文标题】:How do I properly format long compound if statements in Coffeescript 【发布时间】:2011-10-01 08:47:34 【问题描述】:

如果我有一个复杂的 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

【问题讨论】:

如果not bar 在第一个子句中是可能的(正如第二个子句所暗示的那样),那么引用bar.data 将导致错误... 【参考方案1】:

如果下一行以运算符结尾,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 中换行的关键。 如果您不想缩进if statmenet 的正文“更多”,您可以使用then,从与if 相同的级别开始。恕我直言,它更具可读性。 关于缩进的注释;正文不必比if 的非第一行缩进更多。正确语法的唯一规则是(据我所知):1)正文不能与if 的第一行或最后一行具有相同的缩进和2)if 的正文和任何行都不能可以比if 的第一行缩进更少。另请注意,您可以在不同的非第一 if 行上有不同的缩进。 我通常用 2 个制表符缩进非第一个 if 行(以便更明显地看出它们既不在 if 之后也不在 if 内部)和带有 1 个制表符的正文。 【参考方案2】:

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

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 有点不雅;如果foo 不可能是undefined,你可以丢弃它。

【讨论】:

【参考方案3】:

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

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

【讨论】:

如果某些谓词的计算成本很高,并且如果在单个表达式中使用更早的谓词已经可能得出语句的结果,该怎么办?【参考方案4】:

转义换行符对我来说最易读:

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

【讨论】:

【参考方案5】:

当出现大量低级样板时,您应该增加抽象级别

最好的解决方案是:

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

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

【讨论】:

对不起,我不得不对此投反对票。问题是“打破 [a long if statement] 的最犹太方式”,这个答案是非常不相关的。

以上是关于如何正确格式化 Coffeescript 中的长复合 if 语句的主要内容,如果未能解决你的问题,请参考以下文章

放置在另一个文件中的子类的继承(CoffeeScript)

PhpStorm / WebStorm中的CoffeeScript JSDoc支持

有没有更简洁的 Coffeescript 成语呢?

如何将 JSON 数据放入 CoffeeScript?

部分标题标签中的长文本未正确显示

如何将JSON数据放入CoffeeScript?