CoffeeScript,为什么我需要有条件的显式返回

时间:2011-09-26 19:59:55

标签: coffeescript

我正在尝试学习CoffeeScript,并在第一次尝试时创建了这个简单的类:

class test    
  fib: (x) -> 
     x if x == 0 || x == 1   
     (this.fib x-1) + (this.fib x-2)

t = new test
alert(t.fib(6));

此代码不起作用,因为它在if语句中没有return语句时被编译。这有效:

fib: (x) -> 
  return x if x == 0 || x == 1   
  (this.fib x-1) + (this.fib x-2)

为什么我需要明确的回报?根据语言描述,尤其是http://jashkenas.github.com/coffee-script/#expressions,我希望编译器将x表达式转换为返回值。

2 个答案:

答案 0 :(得分:8)

为什么您希望将x表达式转换为返回值?只有方法或函数中的 last 表达式才会转换为返回值。

在Jeremy的if/then/else示例中,有两个可能的最后一个表达式,而coffeescript解析器理解为if/then/else中的情况,这不是你在这里所拥有的:相反,你有表达式没有左值,接着是另一个完全有效的表达式。 (关于if语句本身是否是表达式有一些讨论;可以说,它应该被解读为一个,但if/then/else的编译输出包含一个return关键字then子句和else子句。)

编译器无法读懂你的想法。它不知道你的rvalue x表达式的意图是什么。它只知道在同一范围内的另一个完全有效的表达式跟随它。

获得你想要的效果:

if x == 0 or x == 1
    x
else 
    (@fib x-1) + (@fib x-2)

或者单行:

if x == 0 or x == 1 then x else (@fib x-1) + (@fib x-2)

答案 1 :(得分:2)

这是因为CoffeeScript肯定不知道x if x == 0 || x == 1行是一个return语句。

你想要的是

class test
  fib: (x) ->
    if x == 0 || x == 1
      x
    else
      @fib(x-1) + @fib(x-2)

编译成

(function() {
  var test;
  test = (function() {
    function test() {}
    test.prototype.fib = function(x) {
      if (x === 0 || x === 1) {
        return x;
      } else {
        return this.fib(x - 1) + this.fib(x - 2);
      }
    };
    return test;
  })();
}).call(this);

没有else,条件不是函数的最后一个块,因此不会得到返回处理。