在Dart中,const和final关键字之间有什么区别?


当前回答

何时使用哪个关键字?

一个简单的例子: 使用final:如果你不知道它在编译时的值是多少。例如,当您需要从API获取数据时,就会在运行代码时发生这种情况。

使用const:如果您确定在运行代码时不会更改某个值。例如,当你声明一个始终保持不变的句子。

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

其他回答

dart的网站上有一个帖子,解释得很好。

最后:

"final"表示单赋值:final变量或字段必须有初始化式。一旦赋值,最终变量的值就不能更改。Final修改变量。


常量:

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

Const对象有几个有趣的属性和限制:

它们必须从可以在编译时计算的数据中创建。const对象不能访问运行时计算所需的任何内容。1 + 2是一个有效的const表达式,但new DateTime.now()不是。

它们是深刻的、传递的不可变的。如果final字段包含一个集合,则该集合仍然可以是可变的。如果你有一个const集合,它里面的所有东西也必须是const,递归地。

它们被规范化了。这有点像字符串实习:对于任何给定的const值,无论对const表达式求值多少次,都会创建一个const对象并重新使用。


那么,这意味着什么呢?

Const: If the value you have is computed at runtime (new DateTime.now(), for example), you can not use a const for it. However, if the value is known at compile time (const a = 1;), then you should use const over final. There are 2 other large differences between const and final. Firstly, if you're using const inside a class, you have to declare it as static const rather than just const. Secondly, if you have a const collection, everything inside of that is in const. If you have a final collection, everything inside of that is not final.

最后: 如果在编译时不知道Final的值,则应该在const上使用Final,并且它将在运行时计算/获取。如果你想要一个不可更改的HTTP响应,如果你想从数据库中获取一些东西,或者如果你想从本地文件中读取,请使用final。编译时不知道的任何东西都应该在const上使用final。


话虽如此,const和final都不能被重赋,但final对象中的字段,只要它们本身不是const或final,就可以被重赋(不像const)。

final和const都防止变量被重新赋值(类似于Java中的final或JavaScript中的const)。

这种差异与内存的分配方式有关。在运行时为final变量分配内存,在编译时为const变量分配内存。最后一个修饰符应该是更常用的,因为许多程序变量不需要任何内存,因为程序逻辑不会调用它们进行初始化。对于一个const变量,你基本上是在告诉计算机,“嘿,我需要这个变量的内存,因为我知道我将会需要它。”

以这种方式思考它们可以更容易地理解它们在语法用法上的差异。主要是final变量可以是实例变量,而const必须是类上的静态变量。这是因为实例变量是在运行时创建的,而const变量(根据定义)不是。因此,类上的const变量必须是静态的,这意味着类上存在该变量的单个副本,而不管该类是否实例化。

这段视频相当简单地解释了这一点: https://www.youtube.com/watch?v=9ZZL3iyf4Vk

本文将更深入地讨论并解释两者之间非常重要的语义差异,即final修改变量而const修改值,这本质上归结为只能初始化编译时可派生的const值。

https://news.dartlang.org/2012/06/const-static-final-oh-my.html

通过@Meyi扩展答案

final variable can only be set once and it is initialized when accessed.(for example from code section below if you use the value of biggestNumberOndice only then the value will be initialized and memory will be assigned). const is internally final in nature but the main difference is that its compile time constant which is initialized during compilation even if you don't use its value it will get initialized and will take space in memory. Variable from classes can be final but not constant and if you want a constant at class level make it static const.

代码:

void main() {

    // final demonstration
    final biggestNumberOndice = '6';
    //  biggestNumberOndice = '8';     // Throws an error for reinitialization

    // const
    const smallestNumberOnDice = 1;

}

class TestClass {

    final biggestNumberOndice = '6';

    //const smallestNumberOnDice = 1;  //Throws an error
    //Error .  only static fields can be declared as constants.

    static const smallestNumberOnDice = 1;
}

如果你来自c++,那么Dart中的const在c++中是constexpr,而Dart中的final在c++中是const。

以上内容仅适用于基本类型。 然而在Dart中,标记为final的对象在其成员方面是可变的。

所有这些答案我都可以用简洁的方式描述。

const list = [1, 2, 3];

变量/标识符和值都是const。Like - const list = const [1,2,3] 这就是为什么他们不允许被重新分配。 很适合全局变量。 可以将其用作类变量,但必须设置为静态。Like - static const list =[1,2,3]。

vs:

final list = [1, 2, 3];

变量/标识符是const,而值不是。Like - const list = [1,2,3] 这就是为什么我们可以执行like - list.add(4)