CoffeeScript, Why do I need the explicit return on a conditional
I was trying to learn CoffeeScript, and made this simple class as first try:
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));
This code doesn't work because it gets compiled without开发者_如何学运维 a return statement in the if statement. This works:
fib: (x) ->
return x if x == 0 || x == 1
(this.fib x-1) + (this.fib x-2)
Why do I need the explicit return ? Based on the language description, especially http://jashkenas.github.com/coffee-script/#expressions, I expected the x
expression to be converted to a return by the compiler.
Why would you expect the x
expression to be converted to a return? Only the last expression in a method or function is converted to a return.
In Jeremy's if/then/else
example, there are two possible last expressions, and the coffeescript parser understands to be the case in an if/then/else
, which is not what you have here: instead, you have on expression with no lvalue, followed by another perfectly valid expression. (There's some discussion as to whether or not the if
statement itself is an expression; arguably, it should be read as one, but the compiled output of an if/then/else
contains a return
keyword in both the then
clause and the else
clause.)
The compiler can't read your mind. It doesn't know what your intent is there with that rvalue x
expression. All it knows is that another perfectly valid expression in the same scope follows it.
To get the effect you want:
if x == 0 or x == 1
x
else
(@fib x-1) + (@fib x-2)
Or one-liner:
if x == 0 or x == 1 then x else (@fib x-1) + (@fib x-2)
It's because CoffeeScript doesn't know, for sure, that the x if x == 0 || x == 1
line is a return statement.
What you want is
class test
fib: (x) ->
if x == 0 || x == 1
x
else
@fib(x-1) + @fib(x-2)
Which compiles into
(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);
Without the else
, the conditional isn't the last block of the function, so doesn't get the return treatment.
精彩评论