Dart中为何resultB是Closure而非integer?applyA与applyB差异解析
为什么resultB是Closure类型而非integer?
核心原因是applyA和applyB的闭包嵌套层级与条件判断位置不同,导致调用applyB(one)(addOne)时并未触发最终的函数执行,而是返回了最内层的闭包对象。
两个函数的结构差异
applyA的执行逻辑
dynamic applyA(dynamic x) { if (x is Function) { return (dynamic f) { return (dynamic y) { return f(x(y)); }; }; } else { return (dynamic f) { return f(x); }; } }
当传入的x是普通值(比如整数1)时,外层函数直接进入else分支,返回的是**接受f后立即执行f(x)**的单层闭包。
applyB的执行逻辑
dynamic applyB(dynamic x) { return (dynamic f) { return (dynamic y) { if (x is Function) { return f(x(y)); } else { return f(x); } }; }; }
无论x是普通值还是函数,外层都会先返回两层嵌套的闭包,条件判断被放到了最内层的闭包中,必须传入y参数才会触发判断与执行。
具体调用流程拆解
resultA的执行过程
final resultA = applyA(one)(addOne);
applyA(one):one不是函数,返回(f) => f(one);- 调用
(addOne):直接执行addOne(one)得到结果2,所以resultA是整数类型。
resultB的执行过程
final resultB = applyB(one)(addOne);
applyB(one):返回第一层闭包(f) => 返回第二层闭包;- 调用
(addOne):返回最内层的闭包(y) => {执行addOne(one)}; - 此时未传入
y参数触发闭包执行,所以resultB就是这个未被调用的闭包对象,而非执行后的整数结果。
若要让resultB得到和A一样的结果,只需补充调用闭包(随便传个参数即可,因为y在x非函数时不会被使用):
final resultB = applyB(one)(addOne)(null); // 结果为2
为什么resultC和resultD都是正常整数?
final resultC = applyA(addOne)(addTwo)(one); final resultD = applyB(addOne)(addTwo)(one);
两者都传入了第三层参数one,触发了最内层闭包的执行:
- applyA路径:
applyA(addOne)返回两层闭包,调用(addTwo)得到(y) => addTwo(addOne(y)),再调用(one)执行addTwo(addOne(1))得到4; - applyB路径:
applyB(addOne)返回两层闭包,调用(addTwo)得到(y) => addTwo(addOne(y)),调用(one)同样执行逻辑得到4。
运行输出验证
A=2 B=Closure 'applyB__closure' C=4 D=4
内容的提问来源于stack exchange,提问作者Abarroso
相关产品推荐
相关产品推荐

