Câu trả lời:
Có một bài đăng trên trang web của phi tiêu và nó giải thích nó khá tốt.
Sau cùng:
"Final" có nghĩa là gán đơn: một biến hoặc trường cuối cùng phải có bộ khởi tạo. Khi đã gán một giá trị, giá trị của biến cuối cùng không thể thay đổi. cuối cùng sửa đổi các biến .
Hăng sô:
"const" có nghĩa là phức tạp và tinh tế hơn một chút trong Dart. const sửa đổi các giá trị . Bạn có thể sử dụng nó khi tạo các bộ sưu tập, như const [1, 2, 3] và khi xây dựng các đối tượng (thay vì mới) như const Point (2, 3). Ở đây, const có nghĩa là toàn bộ trạng thái sâu của đối tượng có thể được xác định hoàn toàn tại thời gian biên dịch và đối tượng sẽ bị đóng băng và hoàn toàn bất biến.
Các đối tượng Const có một vài thuộc tính và hạn chế thú vị:
Chúng phải được tạo từ dữ liệu có thể được tính toán tại thời điểm biên dịch. Một đối tượng const không có quyền truy cập vào bất cứ điều gì bạn cần tính toán khi chạy. 1 + 2 là biểu thức const hợp lệ, nhưng DateTime.now () mới thì không.
Họ sâu sắc, bất di bất dịch. Nếu bạn có một trường cuối cùng chứa một bộ sưu tập, bộ sưu tập đó vẫn có thể thay đổi. Nếu bạn có một bộ sưu tập const, mọi thứ trong đó cũng phải là const, đệ quy.
Họ được hợp quy hóa . Đây là loại giống như thực hiện chuỗi: đối với bất kỳ giá trị const đã cho nào, một đối tượng const duy nhất sẽ được tạo và sử dụng lại bất kể số lần biểu thức const được đánh giá.
Const:
Nếu giá trị bạn có được tính trong thời gian chạy ( new DateTime.now()
ví dụ), bạn không thể sử dụng const cho nó. Tuy nhiên, nếu giá trị được biết tại thời gian biên dịch ( const a = 1;
), thì bạn nên sử dụng const
hơn final
. Có 2 sự khác biệt lớn khác giữa const
và final
. Đầu tiên, nếu bạn đang sử dụng const
, bạn phải khai báo nó static const
thay vì chỉ const
. Thứ hai, nếu bạn có một const
bộ sưu tập, tất cả mọi thứ bên trong đó đều nằm trong đó const
. Nếu bạn có một final
bộ sưu tập, mọi thứ bên trong đó không phải là final
.
Cuối cùng:
final
nên được sử dụng const
nếu bạn không biết giá trị tại thời gian biên dịch và nó sẽ được tính / lấy khi chạy. Nếu bạn muốn phản hồi HTTP không thể thay đổi, nếu bạn muốn lấy thứ gì đó từ cơ sở dữ liệu hoặc nếu bạn muốn đọc từ tệp cục bộ, hãy sử dụng final
. Bất cứ điều gì không được biết đến vào thời gian biên dịch sẽ final
kết thúc const
.
Với tất cả những gì đã nói, cả hai const
và final
không thể được chỉ định lại, nhưng các trường trong một final
đối tượng, miễn là chúng không const
hoặc final
, có thể được chỉ định lại (không giống như const
).
const
và khi final
nào? Bạn có biết một số trường hợp sử dụng cho các sửa đổi?
Giá trị phải được biết tại thời gian biên dịch ,
const birthday = "2008/12/26"
Không thể thay đổi sau khi khởi tạo.
Giá trị phải được biết vào thời gian chạy ,
final birthday = getBirthDateFromDB()
Không thể thay đổi sau khi khởi tạo.
Hợp nhất các câu trả lời @Meyi và @ faisal-naseer và So sánh với lập trình nhỏ.
const từ khóa được sử dụng để tạo một biến để lưu trữ giá trị hằng số thời gian biên dịch . Biên dịch giá trị hằng số thời gian là một giá trị sẽ không đổi trong khi biên dịch :-)
Ví dụ 5
là hằng số thời gian biên dịch. Trong khi DateTime.now()
đó không phải là biên dịch thời gian không đổi. Bởi vì phương thức này sẽ trả về thời gian khi dòng đang được thực thi trong thời gian chạy. Vì vậy, chúng ta không thể gán biến DateTime.now()
cho một const
biến.
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();
Nên được khởi tạo ở cùng một dòng .
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;
Tất cả các tuyên bố dưới đây được chấp nhận.
// Without type or var
const a = 5;
// With a type
const int b = 5;
// With var
const var c = 6;
Biến lớp cấp const nên được khởi tạo như dưới đây.
Class A {
static const a = 5;
}
Biến cấp độ const là không thể .
Class A {
// Uncommenting below statement will give compilation error.
// Because const is not possible to be used with instance level
// variable.
// const a = 5;
}
Việc sử dụng chính khác const
được sử dụng để làm cho đối tượng bất biến . Để làm cho một đối tượng lớp bất biến, chúng ta cần sử dụng từ khóa const với hàm tạo và tạo tất cả các trường là cuối cùng như được đề cập dưới đây.
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);
}
chúng ta có thể sử dụng từ khóa const vào danh sách .
const a = const [] - Một biến được a
khởi tạo như const
chứa danh sách các const
đối tượng (nghĩa là Danh sách chỉ chứa các đối tượng hằng số thời gian và bất biến). Vì vậy, chúng tôi không thể chỉ định a
với một danh sách khác .
var a = const [] - Một biến được a
khởi tạo như var
chứa một const
đối tượng danh sách . Vì vậy, chúng ta có thể gán một danh sách khác cho biếna
.
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)];
}
từ khóa cuối cùng cũng được sử dụng để làm cho biến giữ giá trị không đổi . Sau khi khởi tạo, chúng tôi không thể thay đổi giá trị.
final a = 5;
// Uncommenting below statement will give compilation error.
// Because a is declared as final.
// a = 6;
Tất cả các tuyên bố dưới đây được chấp nhận.
// Without type or var
final a = 5;
// With a type
final int b = 5;
// With var
final var c = 6;
Có thể gán giá trị thời gian chạy .
// 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;
Biến cuối cùng của cấp lớp phải được khởi tạo trong cùng một dòng.
Class A {
static final a = 5;
static final b = DateTime.now();
}
Biến cuối cùng của cấp độ sơ thẩm phải được khởi tạo trong cùng một dòng hoặc trong khởi tạo hàm tạo. Giá trị sẽ được đưa vào bộ nhớ khi đối tượng được tạo.
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);
}
Chỉ định một danh sách .
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()];
Mở rộng câu trả lời của @Meyi
biggestNumberOndice
thì giá trị sẽ được khởi tạo và bộ nhớ sẽ được chỉ định).const là bản chất cuối cùng về bản chất nhưng sự khác biệt chính là hằng số thời gian biên dịch của nó được khởi tạo trong quá trình biên dịch ngay cả khi bạn không sử dụng giá trị của nó, nó sẽ được khởi tạo và sẽ chiếm dung lượng trong bộ nhớ.
Biến từ các lớp có thể là cuối cùng nhưng không phải là hằng số và nếu bạn muốn một hằng số ở cấp độ lớp, hãy biến nó thành hằng tĩnh.
Mã số:
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ả hai final
và const
ngăn chặn một biến được gán lại (tương tự như cách final
hoạt động trong Java hoặc cách const
hoạt động trong JavaScript).
Sự khác biệt có liên quan đến cách phân bổ bộ nhớ. Bộ nhớ được phân bổ cho một final
biến trong thời gian chạy và cho một const
biến tại thời gian biên dịch. Công cụ final
sửa đổi nên được sử dụng phổ biến hơn, bởi vì nhiều biến chương trình sẽ không cần bất kỳ bộ nhớ nào vì logic chương trình sẽ không yêu cầu chúng được khởi tạo. Với một const
biến số về cơ bản bạn đang nói với máy tính, "Này, tôi cần bộ nhớ cho biến này trước vì tôi biết tôi sẽ cần nó."
Suy nghĩ về chúng theo cách này giúp dễ hiểu hơn về sự khác biệt trong cách sử dụng cú pháp của chúng. Chủ yếu là một final
biến có thể là một biến thể hiện, nhưng const
phải là một static
biến trên một lớp. Điều này là do các biến thể hiện được tạo ra trong thời gian chạy và const
các biến - theo định nghĩa - thì không. Do đó, const
các biến trên một lớp phải là static
, điều đó có nghĩa đơn giản là một bản sao duy nhất của biến đó tồn tại trên một lớp, bất kể lớp đó có được khởi tạo hay không.
Video này phá vỡ nó khá đơn giản: https://www.youtube.com/watch?v=9ZZL3iyf4Vk
Bài viết này đi sâu hơn và giải thích một sự khác biệt ngữ nghĩa rất quan trọng giữa hai yếu tố này, tức là final
sửa đổi các biến và const
sửa đổi các giá trị, về cơ bản chỉ có thể khởi tạo const
các giá trị có thể phát sinh được trong thời gian biên dịch.
https://news.dartlang.org/2012/06/const-static-final-oh-my.html
Nếu bạn đang đến từ C++
sau đó const
trong Dart
là constexpr
trong C++
và final
trong Dart
là const
trong C++
.
Những điều trên chỉ áp dụng cho các loại nguyên thủy. Tuy nhiên, trong Dart
các đối tượng được đánh dấu final
là có thể thay đổi về các thành viên của nó.
const
trong C ++ hầu như luôn được sử dụng để xác định rằng một đối tượng không thể thay đổi thông qua một tham chiếu hoặc con trỏ cụ thể. final
trong Dart không ngăn đối tượng bị đột biến thông qua biến đó.
Khi nào sử dụng từ khóa nào?
Một ví dụ đơn giản cho cả hai: Sử dụng cuối cùng: Nếu bạn không biết giá trị của nó sẽ là gì vào thời gian biên dịch. Ví dụ: khi bạn có thể cần lấy dữ liệu từ API, điều này xảy ra khi chạy mã của bạn.
Sử dụng const: Nếu bạn chắc chắn rằng giá trị sẽ không bị thay đổi khi chạy mã của bạn. Ví dụ, khi bạn khai báo một câu luôn luôn giữ nguyên.
https://itnext.io/difference-b between-const-and-final-in-dart-78c129d0c573
const
: stackoverflow.com/questions/51576209/ và cách giải thích đơn giảnfinal
là không đổi (không thể gán lại hoặc gán một khi được tạo bằng từ khóa cuối cùng) và bạn phải khởi tạo nó một lần.