mey*_*eyi 99

我在dart的网站上发现了这篇文章,它解释得非常好.

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

最后:

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

常数:

"const"的含义在Dart中有点复杂和微妙.const修改.您可以在创建集合时使用它,例如const [1,2,3],以及构造对象(而不是新的)时,如const Point(2,3).这里,const意味着对象的整个深度状态可以在编译时完全确定,并且对象将被冻结并完全不可变.

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

必须根据可在编译时计算的数据创建它们.const对象无法访问运行时需要计算的任何内容.1 + 2是一个有效的const表达式,但新的DateTime.now()不是.

它们是深刻的,过渡性的一成不变的.如果您有包含集合的final字段,则该集合仍然可以变为可变.如果你有一个const集合,那么其中的所有东西也必须是递归的const.

它们是规范化的.这有点像字符串实习:对于任何给定的const值,无论const表达式被计算多少次,都将创建并重用单个const对象.

  • const关键字用于表示编译时常量。使用const关键字声明的变量是隐式最终的。 (3认同)
  • @CopsOnRoad,您可以查看此视频[Dart Const vs Final](https://www.youtube.com/watch?v=5pe505l9_nE) (3认同)
  • 最后一句话总结得真好。感谢那。 (3认同)

Mah*_*rai 27

合并@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();
Run Code Online (Sandbox Code Playgroud)

应该在同一行初始化.

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;
Run Code Online (Sandbox Code Playgroud)

下面提到的所有陈述均可接受.

// Without type or var
const a = 5;
// With a type
const int b = 5;
// With var
const var c = 6;
Run Code Online (Sandbox Code Playgroud)

类级别const变量应该如下初始化.

Class A {
    static const a = 5;
}
Run Code Online (Sandbox Code Playgroud)

实例级别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;
}
Run Code Online (Sandbox Code Playgroud)

另一个主要用途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);
}
Run Code Online (Sandbox Code Playgroud)

我们可以将const关键字用于列表.

const a = const [] - a 初始化constconst的变量,其中包含对象列表(即,列表应仅包含编译时常量和不可变对象).所以我们无法分配a另一个列表.

var a = const [] - 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)];
}
Run Code Online (Sandbox Code Playgroud)

最后:

final关键字也用于使变量保持常量值.初始化后,我们无法更改该值.

final a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;
Run Code Online (Sandbox Code Playgroud)

下面提到的所有陈述均可接受.

// Without type or var
final a = 5;
// With a type
final int b = 5;
// With var
final var c = 6;
Run Code Online (Sandbox Code Playgroud)

能够分配运行时值.

// 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;
Run Code Online (Sandbox Code Playgroud)

类级最终变量必须在同一行中初始化.

Class A {
    static final a = 5;
    static final b = DateTime.now();
}
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)

分配列表.

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()];
Run Code Online (Sandbox Code Playgroud)


Fai*_*eer 17

通过@Meyi扩展答案

  • 最终变量只能设置一次,并在访问时初始化.(例如,如果您使用值,则从下面的代码部分biggestNumberOndice开始,将初始化该值并分配内存).
  • const本质上是最终的,但主要区别在于它的编译时间常量在编译期间初始化,即使你不使用它的值,它也会被初始化并占用内存空间.

  • 类中的变量可以是final但不是常量,如果你想在类级别使用常量,则使其成为静态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;
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为一个更好的方式来问这个问题是何时更喜欢运行时初始化而不是编译时初始化.... (2认同)

xgq*_*rms 17

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

\n

final表示其初始值必须是固定的,但可以是动态值,等于var固定值。

\n

代码演示

\n
\n

常量

\n
\n
void main() {\n  const sum = 1 + 2;\n  // \xe2\x9c\x85 const can not change its value\n  print("sum = ${sum}");\n  // \xe2\x9a\xa0\xef\xb8\x8f Const variables must be initialized with a constant value.\n  const time = new DateTime.now();\n  // \xe2\x9d\x8c Error: New expression is not a constant expression.\n  print("time = ${time}");\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n
\n

最终的

\n
\n
// new DateTime.now();\n// dynamic timestamp\n\nvoid main() {\n  final sum = 1 + 2;\n  // \xe2\x9c\x85 final can not change its value\n  print("sum = ${sum}");\n  final time = new DateTime.now();\n  // \xe2\x9c\x85 final === var with fixed value\n  print("time = ${time}");\n}\n
Run Code Online (Sandbox Code Playgroud)\n

截图

\n

在此输入图像描述\n在此输入图像描述

\n

参考文献

\n

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

\n


spe*_*naz 11

任何在编译时未知的事情都应该final结束const


Har*_*jem 10

康斯特

值必须在被称为编译时const birth = "2008/12/26"。初始化后无法更改


最后

值必须在被称为运行时final birth = getBirthFromDB()。初始化后无法更改

  • “初始化后无法更改”是不明确的。`final` 变量不能被重新分配,但对象可以被改变。 (8认同)

小智 9

两者finalconst可以防止变量被重新分配(类似于finalJava 中的工作方式或constJavaScript 中的工作方式)。

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

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

该视频非常简单地分解了它: https://www.youtube.com/watch ?v=9ZZL3iyf4Vk

本文更深入地解释了两者之间非常重要的语义差异,即final修改变量和const修改值,这本质上归结为只能初始化可const在编译时导出的值。

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


Mos*_*aev 7

如果您来自,C++那么constinDart就是constexprin C++finalinDart就是constin C++

以上仅适用于原始类型。然而,在Dart标记的对象中final,其成员是可变的。

  • 有点。我认为你可以对原始类型这么说,但对对象则不然。C++ 中的 const 几乎总是用于通过特定的引用或指针来指定对象不可变。Dart 中的“final”不会阻止对象通过该变量发生变化。 (4认同)

erl*_*man 7

final并且const在 dart 中混淆到我们认为它们是相同的水平。

让我们看看它们的区别:

PS 我包含了图像而不是文本,因为我无法轻松地以 Stackoverflow .md 格式列出信息。


Cyb*_*ber 6

简单的话:

常量

值必须在编译时已知,即来自内部文件的值。

示例:API 密钥、应用程序支持的语言或 ie 帮助程序文件中的任何变量,基本上是随应用程序附带的任何内容。

最终的

值必须在运行时已知。

它可以是像上面这样的数据,也可以是在应用程序启动时检查的设备信息,或者是应用程序启动时从 API 或服务器加载的数据,但在应用程序准备使用之前,即您需要检查用户是否无论是否登录,您的应用程序都会从​​服务器加载或检查会话令牌。