是什么在之间'常量“”“”最终'关键字在DART的差异,?

问题描述 投票:49回答:5

是什么在DART constfinal关键字之间的区别?

dart const keyword final
5个回答
76
投票

There is a post on dart's website and it explains it pretty well.

最后:

“最终”表示单赋值:一个最终变量或字段必须具有一个初始化。一旦赋值,最终的变量的值不能改变。最后修改变量。


常数:

“常量”具有以下含义:在箭稍微复杂和微妙。常量修改值。创建集合时,可以使用它,像常量[1,2,3],和类似的常量点构造对象(而不是新的),当(2,3)。在这里,常量意味着对象的整个深州完全可以在编译时和该对象将被冻结,完全不可改变的决定。

const对象有几个有趣的特性和限制:

他们必须从可在编译时计算的数据来创建。 const对象没有获得任何你需要在运行时计算。 1 + 2是一个有效的常量表达式,但是新DateTime.now()不是。

他们是深,及物动词不变。如果你有一个包含集合的最后一个字段,该集合仍然可以是可变的。如果你有一个常量集合,它的一切也必须是const,递归。

他们被规范化。这是有点像字符串实习:对于任何给定常数值,单个const对象将被创建并重新使用不管常量表达式(多个)多少次进行了评价。


那么这是什么意思?

常数: 如果该值是你必须是在运行时计算(new DateTime.now(),例如)值,你不能使用一个const它。但是,如果该值是在编译时(const a = 1;)已知的,那么你应该在const使用final。有constfinal之间2倍大的差异。首先,如果你使用const,你必须将其声明为static const而不仅仅是const。其次,如果你有一个const收藏,这里面一切都在const。如果你有一个final收藏,这里面一切都不是final

最后: final应在const使用,如果你不知道在编译时的值,它会被计算/抓住在运行时。如果你想要一个不能改变的,如果你想从数据库得到的东西,或者如果你想从本地文件读取,使用final HTTP响应。未在编译时已知任何应final超过const


所有这一切说来,无论是constfinal不能被重新分配,但在final对象的字段,只要他们不constfinal,可以重新分配(不像const)。


25
投票

综合@Meyi和@费萨尔 - 纳瑟尔答案,并用很少的编程比较。

const:

用于制造可变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;

类级常量变量应该初始化像的下方。

Class A {
    static const a = 5;
}

实例级别常量变量是不可能的。

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关键字与构造函数,使下面提及的所有字段作为最终等。

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关键字的列表。

一个常量=常数[] - 初始化为a可变const含有const对象的列表(即,列表应只包含编译时间常数和不可改变的对象)。因此,我们不能能够分配a与另一个列表。

一个变种=常数[] - 初始化为a可变var其中包含一个列表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关键字用来使变量保持一个恒定值。初始化完成后,我们可以不能够改变的价值。

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;
// With var
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;

类级最终变量必须在同一行进行初始化。

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

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

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()];

15
投票

通过扩展的@Meyi答案

  • (如果使用biggestNumberOndice的值仅那么该值将被初始化和存储器将被分配例如从下面的代码段)最终变量只能设置一次访问时它被初始化。
  • 常量在本质上是内部最后,主要的区别在于,它即使你不使用它的价值就会得到初始化,将内存空间编译时初始化其编译时间常数。
  • 从类变量可以是最终的,但不是恒定的,如果你想在一流水平恒定,使其静态常量。

码:

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;
}

4
投票

常量

值必须在编译时,const birth = "2008/12/26"是已知的。初始化后不能更改


最后

值必须在运行时,final birth = getBirthFromDB()是已知的。初始化后不能更改


1
投票

如果你是从C++过来然后constDartconstexprC++ finalDartconst C++

上述适用于只有原始类型。然而,在Dart对象标记final是它的成员而言可变的。

© www.soinside.com 2019 - 2024. All rights reserved.