什么时候需要在flutter中使用final作为变量(飞镖)

时间:2018-08-07 03:51:12

标签: dart flutter

对于何时强制使用final作为变量,我感到困惑。

根据StackOverflow上的文档和答案,

  

如果使用非最终字段创建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”强制性吗?还是只是为了优化? 而我应该何时使用“最终”?

2 个答案:

答案 0 :(得分:1)

我认为这与OOP原则SOLID(尤其是开放/关闭原则)更为相关。

在构建窗口小部件时,某些情况下,您需要为构造函数添加一些参数,以定义类的属性。 如果您不对属性使用final,则可以通过其他类(包括状态)来修改它。

您的情况:

print(++widget.hello);

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

我发现了另一个原因StatefulWidget

  

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

答案 1 :(得分:0)

添加 diegoveloper 的内容后,假设您向Order StatefulWidget添加了一个新参数,并且您正在运行该应用程序,因此希望其热加载。

将重新创建订单小部件,但由于是热重载,State对象将保留其现有值。在这种情况下,您应该将该状态保留在State对象中,因为在您的示例中,hello中的值将丢失。

这样,您就不会失去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);

然后再次热重载,该参数为final,并重新创建StatefulWidget,维护State对象,但是根据小部件的新参数,它不会更新其值。为此,您可以使用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);
    });
  }

我偏离了这个问题,但我认为这是相关的。 :)