如何在Dart中编写递归匿名函数?可调用类实现方案探讨
Dart中实现递归匿名函数的几种方式
Dart并没有像Python海象运算符那样的语法,能让匿名函数直接在内部引用自身。不过可以通过以下几种方式实现递归逻辑:
1. 提前声明外部变量(你已尝试的方式)
这种方式需要先定义一个变量,再将匿名函数赋值给它,函数内部通过该变量完成递归调用。比如你写的二叉树层级平均值实现:
var getLevels; List<double> averageOfLevels(TreeNode? root) { return root == null ? [] : (getLevels = (List<TreeNode> level) => level.isNotEmpty ? <double>[level.map((node) => node.val).fold(0, (int l, int r) => l+r) / level.length] + getLevels([for(var node in level) ...[node.left, node.right]].whereType<TreeNode>().toList()) : <double>[])([root]); }
这种写法能正常工作,但必须提前声明外部变量,不够紧凑。
2. 使用可调用类实现(无需额外变量)
可调用类是Dart里的特性,只要类实现了call方法,就可以像调用函数一样调用类的实例。利用这一点,我们可以在call方法里通过this引用自身,实现递归:
阶乘示例
class Factorial { int call(int a) => a == 1 ? 1 : a * this(a - 1); } void main() { print(Factorial()(4)); // 输出24 }
二叉树层级平均值示例
class LevelAverageCalculator { List<double> call(List<TreeNode> level) { if (level.isEmpty) return []; // 计算当前层级平均值 double average = level .map((node) => node.val) .fold(0, (sum, val) => sum + val) / level.length; // 生成下一层级节点列表 List<TreeNode> nextLevel = level .expand((node) => [node.left, node.right]) .whereType<TreeNode>() .toList(); // 递归调用并拼接结果 return [average]..addAll(this(nextLevel)); } } List<double> averageOfLevels(TreeNode? root) { return root == null ? [] : LevelAverageCalculator()([root]); }
这种方式不需要提前声明外部变量,通过类实例的this就能完成递归调用,结构更清晰,也符合你想要的“无需额外提前定义变量”的需求。
内容的提问来源于stack exchange,提问作者loganrussell48
相关产品推荐
相关产品推荐

