繁体   English   中英

什么时候需要在 flutter (dart) 中对变量使用 final

[英]When is it nesessary to use final for variables in flutter (dart)

我对什么时候强制使用 final 变量感到困惑。

根据 StackOverflow 上的文档和答案,

如果使用非 final 字段创建 StatefulWidget 子类,则会导致 DartAnalysis 警告

但是我上了这门课,一切都运行良好

class Order extends StatefulWidget {
  int hello = 1;

  @override
  _OrderState createState() => _OrderState();
}

class _OrderState extends State<Order> {
  pizza _pizzaOrder = new pizza();

  void setSize(String value) {
    setState(() {
      _pizzaOrder.size = value;
      print(++widget.hello);
    });
  }

我做了一个简单的应用程序,从未在程序中的任何地方使用过 final 或 const。 那么在我必须使用“final”/“const”的任何地方都是强制性的吗? 还是只是为了优化? 我什么时候应该使用“final”?

我认为这与 OOP 原则SOLID更相关,特别是打开/关闭原则。

当您构建一个小部件时,在某些情况下,您需要为构造函数提供一些参数,以便定义类的属性。 如果您没有对您的属性使用final ,那么它可以被包括状态在内的其他类修改。

在你的情况下:

print(++widget.hello);

它可以工作,但会导致意外行为,想象一下许多类访问该属性并修改它,您不想要这样吗?

我找到了另一个原因StatefulWidget

StatefulWidget 实例本身是不可变的,并且将它们的可变状态存储在由 createState 方法创建的单独 State 对象中,或者存储在 State 订阅的对象中,例如 Stream 或 ChangeNotifier 对象,这些对象的引用存储在 StatefulWidget 的最终字段中本身。

补充一下diegoveloper已经说过的内容,假设您向Order StatefulWidget添加了一个新参数,并且您正在运行该应用程序,因此希望它热重新加载。

订单小部件将被重新创建,但由于它是一个热重载, State对象将保留在那里,并保留其现有值。 在这种情况下,您应该在 State 对象中保留此状态,但在您的示例中, hello的值将丢失(即将重置回 1)。

这样你就不会丢失hello状态:

class Order extends StatefulWidget {
  Order({this.hello});
  final int hello;

  @override
  _OrderState createState() => _OrderState();
}

class _OrderState extends State<Order> {
  pizza _pizzaOrder = new pizza();
  int _hello;

  @override
  initState() {
    _hello = widget.hello;
  }

  void setSize(String value) {
    setState(() {
      _pizzaOrder.size = value;
      print(++_hello);
    });
  }

但是,让我们说在父小部件中您正在像这样创建它:

Order(hello: 1);

如果您将父级更改为:

Order(hello: 2);

然后再次热重载,参数是最终的,并且 StatefulWidget 被重新创建,状态对象被维护,但是它不会根据小部件的新参数更新它的值。 为此,您将使用didUpdateWidget然后:

class Order extends StatefulWidget {
  Order({this.hello});
  final int hello;

  @override
  _OrderState createState() => _OrderState();
}

class _OrderState extends State<Order> {
  pizza _pizzaOrder = new pizza();
  int _hello;

  @override
  initState() {
    _hello = widget.hello;
  }

  @override
  void didUpdateWidget(Order oldWidget) {
    super.didUpdateWidget(oldWidget);
    setState(() {
      _hello = widget.hello;
    });
  }

  void setSize(String value) {
    setState(() {
      _pizzaOrder.size = value;
      print(++_hello);
    });
  }

我有点偏离了这个问题,但我认为它在某种程度上是相关的。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM