【问题标题】:Why are certain variables marked as final in flutter custom classes?为什么某些变量在flutter自定义类中标记为final?
【发布时间】:2018-10-11 00:06:41
【问题描述】:

我注意到在网上的一些示例中,扩展 StatefulWidget 的类的实例变量标记为 final。这是为什么? 我了解 final 关键字的作用。我不明白为什么要使用扩展小部件类的每个实例变量来声明它。

【问题讨论】:

  • 这很不清楚。你有什么不明白的例子吗?
  • 是的 比如github.com/putraxor/flutter-login-ui/blob/master/lib/… 为什么Widget build(BuildContext context)下声明的变量都标记为final
  • 您的原始问题提出的问题与您在评论中描述的不同。那是一个无状态的小部件。

标签: flutter variables dart final


【解决方案1】:

因为StatefulWidget 继承Widget,标记为@immutable,所以StatefulWidget 的任何子类也必须是不可变的(即所有字段为final)。

如果你创建一个带有非最终字段的StatefulWidget 子类,它将导致这个 Dart 分析警告:

info: 这个类继承自一个标记为@immutable 的类,并且 因此应该是不可变的(所有实例字段必须是最终的)。 (must_be_immutable at [...] lib....dart:23)

以及StatefulWidget documentation中如何使用StatefulWidget的说明:

StatefulWidget 实例本身是不可变的,并存储它们的 可变状态在由 createState 方法,或在该 State 订阅的对象中,用于 示例 Stream 或 ChangeNotifier 对象,其引用是 存储在 StatefulWidget 本身的 final 字段中。

【讨论】:

  • 关于home page 链接中的评论 - 这只是程序员的个人偏好,因为我看不出这些变量是最终的任何实际原因。我不认为这是标准。
【解决方案2】:

这个问题没有固定的答案。这更像是一种偏好。

事实是,如果一个变量可以声明为final,那么为什么声明是这样呢? final 关键字根本不会损害您的代码,并且可能有助于捕获错误。

事实上,您甚至可以启用一个名为 prefer_final_locals 的自定义 linter 规则,如果您有一个从不重新分配的非最终变量,它将导致编译失败。

这允许双重健康检查:不可变变量将无法更改。但同时,如果你忘记改变一个非最终变量,编译器也会警告你。

【讨论】:

  • 这个答案适用于大多数不是 StatefulWidget 的类,但对于 StatefulWidget 有一个直接的答案。另外 - 我认识到 OP 对他们问题的评论有点混淆了问题。
【解决方案3】:

“final”在应用程序中与“const”非常相似,但由于编译时原因不同:请参阅link或以下内容以获得进一步解释:

“final” 表示单一赋值:final 变量或字段必须有一个初始化器。一旦分配了一个值,最终变量的值就不能更改。 final 修改变量

"const" 在 Dart 中具有更复杂和微妙的含义。 const 修改。您可以在创建集合时使用它,例如 const [1, 2, 3],以及在构造对象(而不是 new)时,例如 const Point(2, 3)。这里,const 意味着对象的整个深度状态可以完全在编译时确定,并且对象将被冻结并且完全不可变。

【讨论】:

  • “我了解 final 关键字的作用”。 OP 希望在小部件的上下文中得到答案。
【解决方案4】:

有了 JavaScript/TypeScript 背景,您已经熟悉 const 关键字。在 Java 中,您没有 const,但等于 final。当我开始使用 Dart(用于 Flutter)时,我对这两个可用的关键字感到惊讶。

const String personConst = 'Jeroen';
final String personFinal = 'Jeroen';

personConst = 'Bob'; // Not allowed
personFinal = 'Bob'; // Not allowed

在上面的代码中,我们创建了一个 const 和一个 final 变量,并将我的名字分配给两者。您不能同时重新分配它们。 但是有什么区别呢?

最终

  • 带有final 关键字的变量将在运行时初始化,并且只能分配一次。

  • 在类和函数中,您可以定义一个final 变量。

  • 对于 Flutter 来说,当状态更新时,build 方法中的所有内容都会重新初始化。这包括所有带有final 的变量。

    @override
    Widget build(BuildContext context) {
      // your code
    }
    

常量

  • 带有const 关键字的变量在编译时初始化,并且在运行时已分配。
  • 您不能在类中定义const。但是你可以在一个函数中。
  • 对于 Flutter 而言,当状态更新时,build 方法中的所有内容都不会再次初始化。
  • const 在运行时无法更改。

何时使用哪个关键字?

一个简单的例子:

  • 使用final:如果你不知道它在编译时的值是多少。例如,当您需要从 API 获取数据时,就会在运行代码时发生这种情况。
  • 使用const:如果您确定在运行代码时不会更改某个值。例如,当您声明一个始终保持不变的句子时。

final vs. var

final vs. var:声明变量时,尽可能使用final 而不是 var。这告诉 Dart 在初始化后不应该重新分配变量。如果任何代码尝试再次设置该值,代码分析器将提醒您。如果变量的值在初始化后不应该改变,Dart 的 final 关键字可以帮助您避免与意外突变相关的错误。

您可能已经注意到使用命名参数的一个问题是它们是可选的,有时这是不可取的。

发件人:https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573

【讨论】:

    【解决方案5】:

    根据我观看 Flutter 团队开发的无聊节目的理解。 Final 和 Const 很有帮助,因为它有助于使 Flutter 知道这些值不会被更新,因此算法可以更有效地找出要更新的内容。如果我错了,请有人纠正我

    【讨论】:

      猜你喜欢
      • 2021-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      • 2019-06-03
      • 1970-01-01
      • 2016-07-02
      相关资源
      最近更新 更多