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

时间:2011-07-08 15:02:26

标签: 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

5 个答案:

答案 0 :(得分: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

答案 1 :(得分: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有点不雅观;如果foo undefined无法{{1}},则可以将其丢弃。

答案 2 :(得分: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

答案 3 :(得分:2)

转义换行符对我来说最具可读性:

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

答案 4 :(得分: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为false,则运算符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