如何修改此代码以在 ES6 中启用尾调用优化?
How to modify this code to enable tail call optimization in ES6?
我写了一个递归求和的函数,但它不符合 ES6 中尾调用优化的标准(原因我说不清楚)。
function sum(...values) {
if(!values.length) {
return 0;
}
return values.shift() + sum(...values);
}
如何更改它以符合优化条件?
你需要做
return sum(…);
做一个合适的tail call。在您的示例中,+
操作仍在 递归调用后 执行,这使得它不起作用。
典型的方法是使用带有累加器参数的辅助函数:
function sum(...values) {
function sumTo(acc, values) {
if (!values.length) return acc;
else return sumTo(acc+values.shift(), values); // tail-recursive call
}
return sumTo(0, values);
}
递归列表时,您还可以(ab)使用列表本身:
function sum(...values) {
switch (values.length) {
case 0: return 0;
case 1: return values[0];
default: values.unshift(values.shift()+values.shift());
return sum(...values);
}
}
// or alternatively:
function sum(acc, ...values) {
switch (arguments.length) {
case 0: return 0;
case 1: return acc;
default: values[0] += acc;
return sum(...values);
}
}
我写了一个递归求和的函数,但它不符合 ES6 中尾调用优化的标准(原因我说不清楚)。
function sum(...values) {
if(!values.length) {
return 0;
}
return values.shift() + sum(...values);
}
如何更改它以符合优化条件?
你需要做
return sum(…);
做一个合适的tail call。在您的示例中,+
操作仍在 递归调用后 执行,这使得它不起作用。
典型的方法是使用带有累加器参数的辅助函数:
function sum(...values) {
function sumTo(acc, values) {
if (!values.length) return acc;
else return sumTo(acc+values.shift(), values); // tail-recursive call
}
return sumTo(0, values);
}
递归列表时,您还可以(ab)使用列表本身:
function sum(...values) {
switch (values.length) {
case 0: return 0;
case 1: return values[0];
default: values.unshift(values.shift()+values.shift());
return sum(...values);
}
}
// or alternatively:
function sum(acc, ...values) {
switch (arguments.length) {
case 0: return 0;
case 1: return acc;
default: values[0] += acc;
return sum(...values);
}
}