为什么我们应该避免像飞镖一样

Why we should avoid as in dart

根据 dart lint 规则我不明白我们为什么要 avoid as

If you know the type is correct, use an assertion or assign to a more narrowly-typed variable (this avoids the type check in release mode; as is not compiled out in release mode). If you don't know whether the type is correct, check using is (this avoids the exception that as raises).

如果使用:

在运行时有什么影响
(pm as Person).firstName = 'Seth';

而不是:

Person person = pm;
person.firstName = 'Seth';

为什么这样好:

this avoids the type check in release mode; as is not compiled out in release mode

只是性能提升还是类型错误会不会崩溃?

目前,如果代码完全有效,则两种方法之间的 Dart 语义没有区别。

如果 pm 的类型是 Person 的超类型,则赋值会附加一个隐式的 as Person 强制转换。这就是 Dart 当前添加到一些其他不安全的所谓 "implicit down-cast"。如果它的类型是 Person 的子类型,那么它可以在没有强制转换的情况下分配,并且不会添加任何强制转换。如果两者都不是,那么它根本不可赋值,代码是编译时错误。

某些 JavaScript 的编译器可能会在其 "production mode" 中省略一些检查 。这不遵循 Dart 语义,它是一种 "unsafe optimization",而这正是 lint 文本所暗示的。 如果您的代码在本机运行,而不是在 JavaScript 上运行,则不适用并且 lint 文本具有误导性。 生产模式编译器也可以很容易地省略 as 转换。根据目前没有的文字(或在撰写文字时没有)。

这完全是性能优化。它省略了强制转换,因为它假设它会成功。如果类型错误,那将是 "avoid the crash",但是当以下代码假定类型实际上是正确的时,代码可能很快就会崩溃。这不是避免崩溃的方法,而是一种降低无论如何都不会崩溃的代码开销的方法。

这是 Dart 的当前 版本。 Dart 团队正在积极致力于引入可靠的不可空类型,其中一部分是完全删除隐式向下转型。发生这种情况时,代码 Person person = pm; 将变为无效。你将不得不明确地写 Person person = pm as Person; (没有 隐式 向下转换),或者更有可能你只是写 var person = pm as Person;.

当您知道它会成功时,您仍然应该只我们as。您可以出于多种原因知道这一点,也许是因为某些 class 不变量确保当另一个 属性 具有特定值时,属性 具有特定类型。如果这样做,那么不安全地优化生产模式编译器仍会生成功能代码。

如果您不知道,您应该先测试一下。 if (pm is Person) { .. pm is Person here .. } 测试允许您使用 pm local 变量作为它被测试的类型,至少如果编译器可以确定它的值不'改变。