【问题标题】:When is it nesessary to use final for variables in flutter (dart)什么时候需要对flutter(dart)中的变量使用final
【发布时间】:2019-01-14 01:26:52
【问题描述】:

我对何时强制使用 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”的任何地方都是强制性的吗?还是只是为了优化? 我什么时候应该使用“final”?

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    我觉得这和OOP原理SOLID比较相关,特别是open/close原理。

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

    在你的情况下:

    print(++widget.hello);
    

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

    我找到了另一个原因StatefulWidget

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

    【讨论】:

      【解决方案2】:

      除了 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 被重新创建,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);
          });
        }
      

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

      【讨论】:

      • Order({this.hello}); final int hello = 1; 这会出错。我想你留下了一个错字
      • 是的,复制和粘贴,没有测试.. :) 谢谢,已编辑。
      猜你喜欢
      • 2010-11-05
      • 2013-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多