gpt4 book ai didi

dart - const 构造函数与静态最终规范值

转载 作者:行者123 更新时间:2023-12-03 02:57:07 25 4
gpt4 key购买 nike

根据 this excellent explanation const Dart 中的表达式是“深度不可变”的,这意味着内部的任何内容都不会改变,因此整个表达式将始终表示相同的东西。这对编译器很有用,因为它可以一次生成整个对象图并在每次出现这样的表达式时重新使用它,并且程序员知道这样的表达式——即使它是深度嵌套的——仍然是有用的遵循值(value)语义,不会在我背后做任何事情。

我正在使用编译器的这些优化来使用结构良好的对象模型(例如,而不是将其手动编码为位向量)并且仍然可以获得良好的性能。因为我们也可以通过使用 static final 使它们成为运行时常量来“显式散列”一些值来获得其中的一些好处。成语,问题出现了,在哪种情况下使用这两者中的哪一个是好的风格?

考虑以下示例:

enum ShaftType { RING, SUN, CARRIER }

class Shaft {
final int index;
final ShaftType type;

Shaft(this.type, this.index) {
assert((type == ShaftType.CARRIER) == (index == null));
}
const Shaft.CARRIER()
: type = ShaftType.CARRIER,
index = null;
const Shaft.RING(this.index) : type = ShaftType.RING;
const Shaft.SUN(this.index) : type = ShaftType.SUN;
}

class GearPath {
final Shaft input, output, fixed;

GearPath({this.input, this.output, this.fixed}) {
// input and output must be set
assert(null != input && null != output);

// fixed shaft can't be anything else
assert(fixed != input && fixed != output);
}

GearPath.carrierToFirstRingFixedSun(int i)
: input = const Shaft.CARRIER(),
output = const Shaft.RING(0),
fixed = new Shaft.SUN(i) {}

static final singleFixedSunUp = new GearPath(
input: const Shaft.CARRIER(),
output: const Shaft.RING(0),
fixed: const Shaft.SUN(0),
);

static final directDrive = new GearPath(
input: const Shaft.CARRIER(),
output: const Shaft.CARRIER(),
fixed: null,
);

// ...
}

我做不了主 Shaft(..)GearStage(..)构造函数 const因为我想检查一些约束,但我可以提供特殊情况的构造函数(例如 Shaft.SUN(int i)Shaft.CARRIER() ),它们在设计上符合这些约束(至少部分),并为用户提供这些常见值的易读简写。

另一方面,当 const构造函数没有参数,那么我也可以将它写成 static final成员,就像我对 GearStage.directDrive 所做的那样.如果所有用户都引用这个静态成员而不是重新创建值,我们还可以获得共享内存和快速比较(引用同一对象)的好处。我不能将这个定义的右侧声明为 const,因为它使用了非常量构造函数,但是开发人员可以从上下文中看到这确实是一个常量值,而不是隐藏在静态字段中的全局可变单例。因此,出于实际目的,它应该与 const 构造函数一样好,对吧?

由于我还没有发现这描述了作为最佳实践的任何地方,所以我的问题很简单,这是否确实是在 const 之间进行组合和权衡的好方法构造函数和 static final “命名值实例”?

最后不知道有没有办法声明 GearPath.carrierToFirstRingFixedSun(int i)也作为 const 构造函数?目前我不能,因为 const Shaft.SUN(i)投诉 i不是恒定的。

( full code of example)

最佳答案

Dart 2 将允许您在 const 构造函数中使用断言(只要您的条件可以计算为 const 表达式)。
然后你就可以写:

GearPath({this.input, this.output, this.fixed}) 
: // input and output must be set
assert(null != input && null != output),
// fixed shaft can't be anything else
assert(!identical(fixed, input) && !identical(fixed, output));

在那之前,您不能同时拥有验证和 const 表达式。

您仍然无法制作 GearPath.carrierToFirstRingFixedSun(int i) const 因为它 i不是恒定的。 const Shaft.SUN(i)仍然不是有效的 const 表达式,即使 i是 const 构造函数的参数。每个 const Constructor(...)调用仍然必须只创建一个对象,即使它出现在另一个 const 构造函数的初始值设定项列表中。

作为经验法则,您应该考虑是否将值公开为 const 而不是 final 是您想要 promise 的事情。当您将变量设为 const 时,意味着其他人可以在另一个 const 表达式中使用该值,然后将变量更改为 final 将是一个重大更改。说某事是 const是你应该慎重选择的 promise ,而不仅仅是因为你可以。因此,请考虑变量的用例。如果您没有看到它在其他 const 表达式中使用,那么只需将其设为 final 即可。

关于dart - const 构造函数与静态最终规范值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46989511/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com