企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] 下面的最佳实践描述了如何在Dart中最好地使用变量。 ## 不要显式地将变量初始化为空。 在Dart中,未显式初始化的变量或字段自动被初始化为null。这是由语言可靠地指定的。在Dart中没有“未初始化内存”的概念。添加= null是多余的和不需要的。 ~~~ int _nextId; class LazyId { int _id; int get id { if (_nextId == null) _nextId = 0; if (_id == null) _id = _nextId++; return _id; } } ~~~ 以下是不推荐的写法: ~~~ int _nextId = null; class LazyId { int _id = null; int get id { if (_nextId == null) _nextId = 0; if (_id == null) _id = _nextId++; return _id; } } ~~~ ## 避免储存你能计算的东西。 在设计类时,您通常希望将多个视图公开到相同的底层状态。通常你会看到在构造函数中计算所有视图的代码,然后存储它们: 应该避免的写法: ~~~ class Circle { num radius; num area; num circumference; Circle(num radius) : radius = radius, area = pi * radius * radius, circumference = pi * 2.0 * radius; } ~~~ 这个代码有两个问题。首先,它可能会浪费内存。严格地说,这个区域和周长是缓存。它们是存储的计算,我们可以从已有的其他数据中重新计算。他们用增加的内存换取减少的CPU使用。我们知道我们有一个性能问题值得权衡吗? 更糟糕的是,代码是错误的。缓存的问题是无效——您如何知道何时缓存过期需要重新计算?在这里,我们永远不会这样做,即使半径是可变的。您可以指定一个不同的值,而面积和周长将保留它们以前的、现在不正确的值。 为了正确处理缓存失效,我们需要这样做: 应该避免的写法: ~~~ class Circle { num _radius; num get radius => _radius; set radius(num value) { _radius = value; _recalculate(); } num _area; num get area => _area; num _circumference; num get circumference => _circumference; Circle(this._radius) { _recalculate(); } void _recalculate() { _area = pi * _radius * _radius; _circumference = pi * 2.0 * _radius; } } ~~~ 这需要编写、维护、调试和读取大量代码。相反,您的第一个实现应该是: ~~~ class Circle { num radius; Circle(this.radius); num get area => pi * radius * radius; num get circumference => pi * 2.0 * radius; } ~~~ 这段代码更短,占用的内存更少,也更不容易出错。它存储表示圆所需的最小数据量。没有字段可以不同步,因为只有一个真实的源。 在某些情况下,您可能需要缓存慢速计算的结果,但只有在知道存在性能问题之后,才能这样做,请仔细执行,并留下解释优化的注释。