“句式”和“句式”的区别是什么?和“;final"关键字在Dart?

在Dart中constfinal关键字有什么区别?

157491 次浏览

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

最后:

“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对象并重新使用。


那么,这意味着什么呢?

< p > 常量:
如果你拥有的值是在运行时计算的(例如new DateTime.now()),你可以const a = 1;3对它使用const。然而,如果该值在编译时已知(const a = 1;),则应该使用const而不是final。在constfinal之间还有两个很大的区别。首先,如果你在类中使用const,你必须将它声明为static const而不仅仅是const。其次,如果你有一个const集合,它里面的所有东西都在const中。如果你有一个final集合,它里面的所有东西都是const a = 1;3 final.

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


综上所述,constfinal都不能被重赋,但final对象中的字段,只要它们本身不是constfinal,就可以被重赋(不像const)。

通过@Meyi扩展答案

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

  • 类中的变量可以是final,但不能是constant,如果你想要a 类级别的常量使其为静态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的对象在其成员方面是可变的

合并@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的另一个主要用途是用于生成不可变的对象. c。要使类对象不可变,我们需要在构造函数中使用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关键字到列表

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

var a = const[] -变量a 初始化为__ABC1,其中包含一个列表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;

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

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 birthday = "2008/12/25"
初始化后不能更改。


最后

值必须在< >强运行时< / >强处已知,final birthday = getBirthDateFromDB()
初始化后不能更改。

finalconst都防止变量被重新赋值(类似于Java中的final或JavaScript中的const的工作方式)。

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

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

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

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

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

不能使用final初始化const。例如:

  final myConst = 1;
const myFinal = 2;


final a = myConst; // possible
final b = myFinal; // possible
const c = myConst; // this is not possible
const d = myFinal; // possible

dart中的finalconst令人困惑,以至于我们认为它们是相同的。

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

. < img src = " https://i.stack.imgur.com/uS1Z9.jpg " alt = " / > < / p >

< p >注:我包括图像而不是文本,因为我不能将信息制成表格

.md格式

何时使用哪个关键字?

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

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

< a href = " https://itnext。Io /difference-between-const-and-final-in-dart-78c129d0c573" rel="nofollow noreferrer">https://itnext.io/difference-between-const-and-final-in-dart-78c129d0c573

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

截图

enter image description here enter image description here < / p >

参考文献

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

const是一个编译时常量。

final是一个运行时常数。

编译时不知道的任何东西都应该是final / const

具有final关键字的变量将在运行时初始化,并且只能赋值一次。

具有const关键字的变量在编译时初始化,在运行时已经赋值。

使用final:如果你不知道它在编译时的值是什么。例如,当您需要从API获取数据时,就会在运行代码时发生这种情况。 使用const:如果你确定一个值在运行你的代码时不会被改变。例如,当你声明一个句子总是保持不变。

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

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

与:

final list = [1, 2, 3];
  • 变量/标识符是const,而值不是。比如——const list = [1, 2, 3]
  • 这就是为什么我们可以像- list.add(4)这样执行

简单的单词:

常量

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

示例:API键,应用程序支持的语言或helper文件中的任何变量,基本上是应用程序附带的任何东西。

最后

Value必须在运行时处已知。

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

. 答案就在图像本身