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


当前回答

dart中的Final和const很容易混淆,以至于我们认为它们是相同的。

让我们来看看它们的区别:

附注:我包括图像而不是文本,因为我不能将信息制成表格 在Stackoverflow .md格式轻松。

其他回答

合并@Meyi和@faisal-naseer的答案,并与小程序进行比较。

常量:

Const关键字,用于创建存储编译时常量值的变量。编译时常量值是一个在编译时为常量的值:-)

例如,5是一个编译时常数。而DateTime.now()不是编译时间常量。因为这个方法将返回行在运行时被执行的时间。所以我们不能将DateTime.now()赋值给一个const变量。

const a = 5;
// Uncommenting below statement will cause compile time error.
// Because we can't able to assign a runtime value to a const variable
// const b = DateTime.now();

应在同一行进行初始化。

const a = 5;
// Uncommenting below 2 statement will cause compilation error.
// Because const variable must be initialized at the same line.
// const b;
// b = 6;

以下所有陈述均可接受。

// Without type or var
const a = 5;
// With a type
const int b = 5;
// With var
const var c = 6;

类级别的const变量应该像下面这样初始化。

Class A {
    static const a = 5;
}

实例级const变量不可用。

Class A {
    // Uncommenting below statement will give compilation error.
    // Because const is not possible to be used with instance level 
    // variable.
    // const a = 5;
}

const的另一个主要用途是使对象不可变。要使类对象不可变,我们需要使用const关键字和构造函数,并将所有字段设置为final,如下所述。

Class A {
    final a, b;
    const A(this.a, this.b);
}

void main () {
    // There is no way to change a field of object once it's 
    // initialized.
    const immutableObja = const A(5, 6);
    // Uncommenting below statement will give compilation error.
    // Because you are trying to reinitialize a const variable
    // with other value
    // immutableObja = const A(7, 9);

    // But the below one is not the same. Because we are mentioning objA 
    // is a variable of a class A. Not const. So we can able to assign
    // another object of class A to objA.
    A objA = const A(8, 9);
    // Below statement is acceptable.
    objA = const A(10, 11);
}

我们可以对列表使用const关键字。

const a = const[] -初始化为const的变量a,它包含一个const对象的列表(例如:,列表应该只包含编译时间常量和不可变对象)。所以我们不能用另一个列表赋值a。

var a = const[] -初始化为var的变量a,其中包含一个const对象列表。所以我们可以将另一个列表赋值给变量a。

Class A {
    final a, b;
    const A(this.a, this.b);
}

class B {
    B(){ // Doing something }
}

void main() {
    const constantListOfInt = const [5, 6, 7,
                 // Uncommenting below statement give compilation error.
                 // Because we are trying to add a runtime value
                 // to a constant list
                 // DateTime.now().millisecondsSinceEpoch
              ];
    const constantListOfConstantObjA = const [
        A(5, 6),
        A(55, 88),
        A(100, 9),
    ];
    // Uncommenting below 2 statements will give compilation error.
    // Because we are trying to reinitialize with a new list.
    // constantListOfInt = [8, 9, 10];
    // constantListOfConstantObjA = const[A(55, 77)];

    // But the following lines are little different. Because we are just
    // trying to assign a list of constant values to a variable. Which 
    // is acceptable
    var variableWithConstantList = const [5, 6, 7];
    variableWithConstantList = const [10, 11, 15];
    var variableOfConstantListOfObjA = const [A(5, 8), A(7, 9), A(10, 4)];
    variableWithConstantList = const [A(9, 10)];
}

最后:

Final关键字还用于使变量保持恒定值。一旦初始化,就不能更改值。

final a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;

以下所有陈述均可接受。

// Without type or var
final a = 5;
// With a type
final int b = 5;
// Can't use var along with final keyword. Uncommenting below line cause compilation issue.
// final var c = 6;

能够分配运行时值。

// DateTime.now() will return the time when the line is getting
// executed. Which is a runtime value.
final a = DateTime.now();
var b = 5;
final c = b;

类级final变量必须在同一行中初始化。

Class A {
    static final a = 5;
    static final b = DateTime.now();
}

实例级final变量必须在同一行或在构造函数初始化中初始化。该值将在创建对象时被放入内存中。

Class A {
    final a = 5;
}

// Constructor with a parameter.
Class B {
    final b;
    B(this.b);
}

// Constructor with multiple parameter.
Class C {
    final c;
    C(this.c, int d) {
        // Do something with d
    }
}

void main() {
    A objA = new A();
    B objB = new B(5);
    C objC = new C(5, 6);
}

分配一个列表。

final a = [5, 6, 7, 5.6, A()];
// Uncommenting Below statement will give compilation error.
// Because we are trying to reinitialize the object with another list.
// a = [9.9, 10, B()];

Const表示它的初始值必须是固定的,不能是动态值;

Final意味着它的初始值必须是固定的,但可以是一个动态值,等于具有固定值的var。

代码演示

常量

void main() {
  const sum = 1 + 2;
  // ✅ const can not change its value
  print("sum = ${sum}");
  // ⚠️ Const variables must be initialized with a constant value.
  const time = new DateTime.now();
  // ❌ Error: New expression is not a constant expression.
  print("time = ${time}");
}

最后

// new DateTime.now();
// dynamic timestamp

void main() {
  final sum = 1 + 2;
  // ✅ final can not change its value
  print("sum = ${sum}");
  final time = new DateTime.now();
  // ✅ final === var with fixed value
  print("time = ${time}");
}

截图

refs

https://dart.dev/guides/language/language-tour#final-and-const

通过@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;
}

答案就在图像本身。

dart中的Final和const很容易混淆,以至于我们认为它们是相同的。

让我们来看看它们的区别:

附注:我包括图像而不是文本,因为我不能将信息制成表格 在Stackoverflow .md格式轻松。