如何检测泛型类型是否实现+运算符以实现线段树sum构造函数?
解决线段树
sum命名构造函数的泛型运算符约束问题 方案1:定义Summable<T>接口(类型安全首选)
这是最规范的做法,通过接口约束泛型类型必须支持加法运算符,能在编译期就排查类型错误。
首先定义接口:
abstract class Summable<T> { T operator +(T other); }
然后修改SegmentTree.sum构造函数,给泛型T加上接口约束:
typedef Combiner<T> = T Function(T a, T b); class SegmentTree<T> { final Combiner<T> combiner; final List<T> _data; // 现有默认构造函数 SegmentTree(List<T> data, {required this.combiner}) : _data = List.from(data); // sum命名构造函数,约束T必须实现Summable SegmentTree.sum(List<T> data) : combiner = (a, b) => a + b, _data = List.from(data) where T extends Summable<T>; // 现有min构造函数示例 SegmentTree.min(List<T> data, {Comparator<T>? comparator}) : combiner = comparator != null ? (a, b) => comparator(a, b) <= 0 ? a : b : (a, b) => (a as Comparable<T>).compareTo(b) <= 0 ? a : b, _data = List.from(data); }
当你尝试用不支持+的类型创建SegmentTree.sum时,编译器会直接报错。对于int、double这类原生支持+的类型,只需通过扩展实现Summable接口即可:
extension IntSummable on int implements Summable<int> { @override int operator +(int other) => super + other; } extension DoubleSummable on double implements Summable<double> { @override double operator +(double other) => super + other; }
方案2:利用现有Combiner<T> typedef,提供默认组合函数(快速实现但无编译检查)
如果不想引入接口,可以直接给sum构造函数提供默认的加法组合器,但这种方式没有编译期类型检查,若传入的T不支持+运算符,会在运行时抛出错误。
实现代码:
typedef Combiner<T> = T Function(T a, T b); class SegmentTree<T> { final Combiner<T> combiner; final List<T> _data; SegmentTree(List<T> data, {required this.combiner}) : _data = List.from(data); // sum构造函数,默认使用加法组合器 SegmentTree.sum(List<T> data, {Combiner<T>? combiner}) : combiner = combiner ?? ((a, b) => a + b as T), _data = List.from(data); }
这种方式无需修改现有类型,原生支持+的类型(int、double)可直接使用,但误用不支持加法的类型时,只能在运行时发现错误,调试成本更高。
方案对比
| 方案 | 类型安全性 | 实现复杂度 | 原生类型支持 |
|---|---|---|---|
| Summable接口约束 | 编译时检查 | 中等(需定义接口+扩展) | 需扩展实现 |
| 默认Combiner函数 | 运行时检查 | 低 | 直接支持 |
若项目对类型安全要求高,优先选方案1;若需快速实现功能且能确保传入的T都支持加法,方案2可快速落地。
内容的提问来源于stack exchange,提问作者loganrussell48
相关产品推荐
相关产品推荐

