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

Dart含计算字段的不可变类:如何用多构造器生成const对象?

在Dart中实现支持const的三点构造Circle类

要实现支持const的三点构造Circle类,核心是利用Dart 2.14+引入的const静态函数,配合const命名构造器完成编译时计算,同时保持对象不可变性。

解决方案代码

import 'dart:math';

class Circle {
  final Point center;
  final double radius;

  // 基础const构造器
  const Circle(this.center, this.radius);

  // 支持const的三点命名构造器
  const Circle.fromPoints(Point p1, Point p2, Point p3)
      : center = _getCenter(p1, p2, p3),
        radius = _getCenter(p1, p2, p3).distanceTo(p1);

  // const静态方法:必须是纯函数,无副作用,仅依赖编译时常量参数
  static const Point _getCenter(Point p1, Point p2, Point p3) {
    // 三点求圆心的数学实现(确保逻辑纯、无运行时依赖)
    final ax = p1.x, ay = p1.y;
    final bx = p2.x, by = p2.y;
    final cx = p3.x, cy = p3.y;

    final d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by));
    final ux = ((ax*ax + ay*ay) * (by - cy) + (bx*bx + by*by) * (cy - ay) + (cx*cx + cy*cy) * (ay - by)) / d;
    final uy = ((ax*ax + ay*ay) * (cx - bx) + (bx*bx + by*by) * (ax - cx) + (cx*cx + cy*cy) * (bx - ax)) / d;

    return Point(ux, uy);
  }
}

关键说明

  1. const命名构造器:Circle.fromPoints被声明为const,要求所有初始化逻辑必须在编译时完成,不能包含运行时代码块。
  2. const静态函数:_getCenter必须标记为const,确保它是纯函数——只接收编译时常量参数,执行无副作用的数学运算,返回编译时常量结果。
  3. 使用方式:当传入的三个Point都是const实例时,可直接生成const Circle对象:
void main() {
  const p1 = Point(-1, 0);
  const p2 = Point(0, 1);
  const p3 = Point(1, 0);
  
  const circle = Circle.fromPoints(p1, p2, p3);
  print(circle.center); // 输出 (0.0, 0.0)
  print(circle.radius); // 输出 1.0
}

为什么之前的方法行不通?

  • 工厂构造器:工厂构造器无法被标记为const,因为它允许执行运行时逻辑,因此无法生成const实例。
  • 外部计算失败:之前的getCenter如果不是const方法,计算出的center变量是运行时变量,无法传入const Circle构造器(const构造器只接受编译时常量参数)。

局限性

如果三点求圆心的逻辑依赖运行时状态(比如动态输入、随机值等),则无法使用const构造器,此时只能用工厂构造器生成不可变对象(保留final字段),但无法获得const实例的编译时优化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 14:45:39