You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
  1. applyA(one):one不是函数,返回(f) => f(one);
  2. 调用(addOne):直接执行addOne(one)得到结果2,所以resultA是整数类型。

resultB的执行过程

final resultB = applyB(one)(addOne);
  1. applyB(one):返回第一层闭包(f) => 返回第二层闭包;
  2. 调用(addOne):返回最内层的闭包(y) => {执行addOne(one)};
  3. 此时未传入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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:43:18