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

如何解决Dart泛型类型下算术运算符不支持的编译错误?

在Dart中为泛型类型支持基础算术运算符的解决方案

问题重现

源代码

import "dart:math";

abstract class Shape<T> {
  T getArea();
}

class Circle<T> extends Shape<T> {
  T radius;
  Circle({required this.radius});

  @override
  T getArea() => radius * radius * pi;
}

class Square<T> extends Shape<T> {
  T length;

  Square({required this.length});

  @override
  T getArea() => length! * length!;
}

void main() {
  Circle circle = Circle(radius: 0);
  print(circle.getArea());

  Circle circle2 = Circle(radius: 10);
  print(circle2.getArea());

  Square square = Square(length: 20.0);
  print(square.getArea());
}

编译器报错

Error: The operator '*' isn't defined for the class 'Object'.
 - 'Object' is from 'dart:core'.
Try correcting the operator to an existing operator, or defining a '*' operator.

解决方案

1. 约束泛型为num类型

Dart中num是int和double的父类,自带算术运算符,直接约束泛型继承自num即可解决问题:

import "dart:math";

abstract class Shape<T extends num> {
  T getArea();
}

class Circle<T extends num> extends Shape<T> {
  T radius;
  Circle({required this.radius});

  @override
  T getArea() => (radius * radius * pi) as T;
}

class Square<T extends num> extends Shape<T> {
  T length;

  Square({required this.length});

  @override
  T getArea() => length * length;
}

void main() {
  Circle<int> circle = Circle(radius: 0);
  print(circle.getArea()); // 0

  Circle<int> circle2 = Circle(radius: 10);
  print(circle2.getArea()); // 314(pi与int相乘结果为double,as T会自动取整)

  Square<double> square = Square(length: 20.0);
  print(square.getArea()); // 400.0
}

注:radius * radius * pi的结果默认是double,通过as T转换回泛型类型,若需精确控制数值类型可根据场景调整。

2. 定义算术运算抽象接口(支持自定义数值类型)

如果需要支持自定义数值类型(比如自定义Decimal类),可以先定义支持乘法的抽象接口,再约束泛型实现该接口:

import "dart:math";

abstract class Multipliable<T> {
  T operator *(T other);
}

abstract class Shape<T extends Multipliable<T>> {
  T getArea();
}

class Circle<T extends Multipliable<T>> extends Shape<T> {
  T radius;
  Circle({required this.radius});

  @override
  T getArea() {
    final squared = radius * radius;
    return (squared as dynamic) * pi as T;
  }
}

// 为int扩展Multipliable接口(int本身已支持*,仅作示例)
extension IntMultipliable on int implements Multipliable<int> {
  @override
  int operator *(int other) => super * other;
}

// 为double扩展Multipliable接口
extension DoubleMultipliable on double implements Multipliable<double> {
  @override
  double operator *(double other) => super * other;
}

class Square<T extends Multipliable<T>> extends Shape<T> {
  T length;

  Square({required this.length});

  @override
  T getArea() => length * length;
}

void main() {
  Circle<int> circle = Circle(radius: 0);
  print(circle.getArea()); // 0

  Circle<double> circle2 = Circle(radius: 10.0);
  print(circle2.getArea()); // 314.1592653589793

  Square<double> square = Square(length: 20.0);
  print(square.getArea()); // 400.0
}

这种方式灵活性更高,适配自定义数值类型的扩展需求。

3. 使用动态类型(不推荐)

可以通过dynamic绕过编译检查,但会丢失类型安全性,运行时传入不支持*的类型会抛出异常,仅适合临时调试场景:

import "dart:math";

abstract class Shape<T> {
  T getArea();
}

class Circle<T> extends Shape<T> {
  T radius;
  Circle({required this.radius});

  @override
  T getArea() => (radius as dynamic) * radius * pi as T;
}

class Square<T> extends Shape<T> {
  T length;

  Square({required this.length});

  @override
  T getArea() => (length as dynamic) * length as T;
}

void main() {
  Circle<int> circle = Circle(radius: 0);
  print(circle.getArea()); // 0

  Circle<double> circle2 = Circle(radius: 10.0);
  print(circle2.getArea()); // 314.1592653589793

  Square<double> square = Square(length: 20.0);
  print(square.getArea()); // 400.0
}

内容的提问来源于stack exchange,提问作者user8234870

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 20:15:37