【问题标题】:const constructor and const object in FlutterFlutter 中的 const 构造函数和 const 对象
【发布时间】:2021-06-13 16:17:58
【问题描述】:

我对 Dart (Flutter) 中的 const 构造函数感到喘不过气来。

假设我有 StatelessWidget 和 const 构造函数

class ChildWidget extends StatelessWidget {
  final String myText;

  const ChildWidget(
      {this.myText = ''});

  @override
  Widget build(BuildContext context) {
    return Text(
      myText
    );
  }
}

并在父窗口小部件中使用它

class _ParentWidgetState extends State<ParentWidget> {
  String myText = 'Hello World';
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            const ChildWidget(myText: myText),
          ],
        ),
      ),
    );
  }
}

显示 myText 是无效 const 的错误。但是当我删除 ChildWidget 之前的 const 关键字时,一切都会好起来的。怎么了? have 和没有 const 关键字有什么区别?

我认为 const 关键字会触发 ChildWidget 中的 const 构造函数。也许 Flutter 会隐式创建具有相同参数的普通构造函数,例如 const one,并在没有 const 关键字时触发 this?

请给我解释一下。非常感谢,祝您有美好的一天。

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    const 表示“在编译时已知”。如果您使用 const 关键字调用构造函数,则它将在编译时创建,并将构建到应用程序二进制文件中:

    const child1 = ChildWidget(myText: "text");
    const child2 = ChildWidget(myText: "text");
    print(identical(child1, child2));  // prints "true"
    

    请注意,这只发生在应用程序以 Ahead-of-time 模式 (AOT) 编译时。在 Flutter 中,这意味着“profile”或“release”模式。

    您的示例失败的原因是因为myText 在编译时未知。

    这似乎令人困惑,因为您输入了 'Hello World',这在编译时是明确已知的,但编译器无法证明这一点,因此它会拒绝它。

    myText 被声明为 String,但要让 dart 知道它是 const,还必须使用 const 关键字声明。

    如果您将String myText = "Hello World"; 替换为:

    static const myText = 'Hello World';
    

    编译器会知道它是 const,然后你可以在 const ChildWidget() 中使用它

    附:你是正确的,Dart 在 const 构造函数旁边创建了一个非const 构造函数。不使用 constconst 构造函数是完全可以的:

    children: [
      ChildWidget(myText: myText)  // perfectly fine
    ]
    

    【讨论】:

    • 是的。我现在明白了。也许 Dart 从具有精确参数的 const 构造函数中克隆非常量?我刚刚使用 put @required 注释对其进行了测试,并且 const 和非 const 构造函数都需要它。
    • 没错,构造函数上的 const 关键字告诉 dart 编译器“这是可以制成编译时常量的东西”,但它始终可以像常规构造函数一样使用相同的参数
    • 我明白了。非常感谢:D
    猜你喜欢
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    • 2012-02-03
    • 2021-11-10
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    相关资源
    最近更新 更多