gpt4 book ai didi

即使不存在递归函数,JavaScript 堆栈也会溢出

转载 作者:行者123 更新时间:2023-12-01 23:27:33 26 4
gpt4 key购买 nike

假设我们想通过将 lambda 用作表示我们要添加新数据的位置的“孔”来构建大型结构。例如,这里我们使用该想法构建 [0,[1,[2,null]]]:

builder_0 = hole => hole;                // hole => hole;
builder_1 = hole => builder_0([0,hole]); // hole => [0, hole];
builder_2 = hole => builder_1([1,hole]); // hole => [0, [1, hole]];
builder_3 = hole => builder_2([2,hole]); // hole => [0, [1, [2, hole]]];

// prints [0,[1,[2,null]]], but will stack overflows if too many lines
console.log(JSON.stringify(builder_3(null)));

这很好用。我们也可以循环执行:

let builder = hole => hole;
for (let i = 0; i < 1000; ++i) {
let last_builder = builder;
builder = hole => last_builder([i, hole]);
};
console.log(builder(null));

这也有效,但如果限制大于 10000,该算法将堆栈溢出。问题在于,由于 last_builder([i,hole]) 未在 hole => ... 闭包内进行评估,因此它将构建未评估的 lambda block 这将迅速消耗整个堆栈。请注意,[0,[1,[2,null]]] 只是一个无用的示例,JavaScript 将无法使用上述基于孔的技术构建任何 大型结构(想想树、JSON、不可变容器等等)。

尾调用优化和蹦床在这里无济于事,因为我们甚至没有开始的递归函数。是否有任何聪明的技巧可以让这种函数式惯用语在没有堆栈溢出的情况下工作?

最佳答案

当您转译功能代码时,您可以让自己在 JS 部分不“功能化”。因此,您无需递归即可创建所需的数据结构:

const builder = (count,hole) => {
let arr = [hole];
let i = 0;
while (count--) arr = [count,arr]
return arr;
}

console.log(builder(22333,null))

(请在浏览器控制台试一试,代码片段工具无法重现)

关于即使不存在递归函数,JavaScript 堆栈也会溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66970999/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com