Biến và các kiểu dữ liệu trong Dart
OK, như vậy là trong Bài 1. Cấu trúc một chương trình Flutter/Dart, các bạn đã biết sơ qua về cấu trúc và cách chạy (biên dịch) một chương trình viết bằng Dart/Flutter.
Tuy nhiên, một chương trình tin học thông thường gồm rất nhiều câu lệnh xử lý trên dữ liệu (dữ liệu do người dùng nhập vào, dữ liệu tự sinh ra trong quá trình tính toán, dữ liệu lấy từ các tệp trên máy tính….) Và để làm việc (tính toán, xử lý) dữ liệu đó, chúng ta cần đến các biến để lưu trữ chúng.
1. Khai báo biến trong chương trình Dart
1.1. Cú pháp khai báo biến trong Dart
Để khai báo một biến trong chương trình, chúng ta sử dụng cú pháp:
var tên_biến;
hoặc kiểu_dữ_liệu_của_biến tên_biến;
Trong các phiên bản cũ, khi khai báo theo cách trên, Dart sẽ gán cho các biến một giá trị mặc định là null
. Bắt đầu từ phiên bản 2.0, Dart/Flutter chính thức hỗ trợ null safety
, nên sẽ không gán giá trị mặc định null
nữa mà bạn bắt buộc phải cho biến một giá trị trước khi sử dụng. Do đó, thông thường chúng ta sẽ khai báo biến như sau:
var tên_biến = giá_trị;
hoặc kiểu_dữ_liệu_của_biến tên_biến = giá_trị;
Ví dụ
void main() { var name = 'Phuong'; int age = 30; }
Nếu muốn biến có thể nhận giá trị null
, bạn thêm kí tự ?
vào sau kiểu_dữ_liệu_của_biến
, chẳng hạn
void main() { var name = 'Phuong'; print(name);//kết quả Phuong int? age = 30; print(age);//kết quả 30 age = null; print(age);//kết quả null }
Một ví dụ nữa
main() { int? a; print(a.runtimeType); //kết quả kiểu Null print(a); //kết quả null a = 5; print(a.runtimeType); //kết quả kiểu int a = null; print(a.runtimeType);////kết quả kiểu Null }
Bạn có thể xem thêm về Null safety Dart / Null safety Flutter là gì?
Khi khai báo biến sử dụng từ khóa var
thì khi sử dụng đến biến đó, trình biên dịch Dart sẽ tự xác định kiểu dữ liệu của biến cho chúng ta.
Ví dụ var x;
để khai báo một biến có tên là x
. Viết int x;
để khai báo một biến kiểu số nguyên int
và có tên là x
.
Khai báo nhiều biến cùng lúc [thường các biến có cùng kiểu], chúng ta sử dụng cú pháp:
var tên_biến1, tên_biến2;
hoặc kiểu_dữ_liệu_của_biến tên_biến1, tên_biến2, tên_biến3;
1.2. Giá trị ban đầu của biến
Xét chương trình sau sử dụng hai biến kiểu số nguyên int
là a
và b
, thực hiện phép cộng hai số a
và b
rồi in kết quả ra màn hình.
void main() { int a, b; print(a+b); }
Tuy nhiên khi chạy chương trình, trình biên dịch báo lỗi như hình sau:
Nguyên nhân là chúng ta mới khai báo hai biến a
và b
chứ chưa cung cấp cho chúng một giá trị nào cả. Do đó không thể thực hiện được phép cộng.
Chúng ta tiến hành cung cấp cho hai biến a
,b
các giá trị, chương trình chạy thành công, kết quả thu được là 9
:
Chúng ta có thể vừa khai báo biến, vừa cung cấp cho biến một giá trị mặc định khởi đầu như trong ví dụ sau:
void main() { int a = 5; int b = 4; print(a+b); }
hoặc viết gọn hơn
void main() { int a = 5, b = 4; print(a+b); }
1.3. Kiểu của biến
Nếu khai báo với từ khóa var
, kiểu của biến sẽ được Dart tự động xác định. Nếu muốn chỉ định kiểu của biến, chúng ta đã biết cách khai báo ở trên. Tuy nhiên, đối với những biến nhận giá trị thuộc mọi kiểu, chúng ta có thể khai báo chúng là kiểu dynamic
hoặc Object
.
void main() { dynamic a = 4; dynamic b; print(a.runtimeType); a = 'Phuong'; print(a.runtimeType); print(b.runtimeType); }
Khi chạy chương trình sẽ được kết quả như hình sau:
Nếu khai báo biến có kiểu dynamic
thì giá trị mặc định của biến sẽ là null
còn khai báo Object
thì biến sẽ không có giá trị mặc định. Ví dụ sau, khai báo biến a
có kiểu dynamic
thì a
sẽ nhận giá trị mặc định là null,
còn biến b
khai báo kiểu Object
thì sẽ không có giá trị mặc định nào cả, kể cả giá trị null.
Do đó hãy cẩn thận.
1.4. Sự khác nhau giữa từ khoá var và dynamic
Nếu bạn khai báo biến bằng từ khoá var
và gán giá trị mặc định ngay thì biến sẽ có kiểu là kiểu của giá trị mặc định đó, nếu không thì biến sẽ có kiểu dynamic
.
void main() { var a; print(a.runtimeType); //Null vì giá trị mặc định của dynamic là null a = 5; //OK print(a.runtimeType); //kiểu int a = 'Phuong'; //OK print(a.runtimeType);//kiểu String var b = 5; print(b.runtimeType);//Kiểu int b = 3; //OK b = 'five'; //Erros }
Dart cũng cung cấp một toán tử đặc biệt ??
, gọi là Null-aware để đảm bảo null safe trong quá trình thực thi code.
Sử dụng toán tử ??=
, để gán một giá trị cho biến nếu và chỉ nếu biến đó đang có giá trị null
.
main() { var a; //biến kiểu dynamic a, mặc định nhận giá trị null a ??= 3; //Gán 3 cho a nếu a đang có giá trị null, phép gán thành công print(a); //Phép gán trên thành công nên a nhận giá trị 3 a ??= 5; //Gán 5 cho a nếu a đang có giá trị null, phép gán không thành công print(a); //a vẫn có giá trị như lúc trước khi thực hiện phép gán }
Một toán tử null-aware khác là ??
, toán tử này trả về biểu thức nằm bên trái toán tử ??
nếu và chỉ nếu biểu thức đó có giá trị khác null
, ngược lại thì trả về biểu thức nằm phía bên phải.
print(1 ?? 3); //In ra 1. print(null ?? 12); // In ra 12.
1.4. Quy tắc đặt tên trong Dart
Trong cú pháp khai báo trên, tên_biến
được đặt tên theo các quy tắc bắt buộc sau:
- Tên phải bắt đầu bằng kí tự từ
a
đếnz
, hoặc từA
đếnZ
hoặc dấu gạch dưới_
và theo sau là chữ hoặc số. - Tên có phân biệt chữ HOA và chữ thường, do đó
ten_bien
vàTen_Bien
là hai tên khác nhau.
Ngoài các quy tắc bắt buộc phải tuân theo đó, chúng ta nên đặt tên theo các quy ước ngầm sau:
- Nên đặt tên có ý nghĩa, điều này giúp việc đọc hiểu code được dễ dàng hơn.
- Đặt tên ngắn gọn, giúp việc gõ code được nhanh hơn, thường chúng ta sẽ viết tắt tên bằng cách viết HOA chữ cái đầu của từ viết tắt, ví dụ
IOStream
InputOutputStream...
- Nên đặt tên kiểu
UpperCamelCase
cho lớpclass
,enums
, tham số (chữ đầu của từ là chữ in ví dụHttpRequest
) - Tên file, thư viện viết chữ thường, các từ nối với nhau bởi
_
ví dụabc_xyz.dart
- Biến, hằng, object đặt tên kiểu
lowerCamelCase
, chữ đầu các từ viết IN HOA, trừ từ đầu tiên ( ví dụdefaultTimeout
)
1.3. Khai báo hằng số trong Dart
Để khai báo một hằng số trong Dart, chúng ta sử dụng cú pháp
const tên_hằng_số = giá_trị;
Ví dụ, sử dụng const pi = 3.1415926;
để khai báo hằng số có tên pi
và có giá trị bằng 3.1415926
2. Các kiểu dữ liệu trong Dart
Dart hỗ trợ các kiểu dữ liệu xây dựng sẵn (built-in types) sau:
- Kiểu số
num
gồm có hai kiểu con là kiểu số nguyênint
, số thựcdouble
- Kiểu xâu (kiểu chuỗi)
String
- Kiểu logic
bool
- Kiểu
null
- Kiểu danh sách
List
tương tự như kiểu mảngarrays
trong các ngôn ngữ khác - Kiểu tập hợp
set
- Kiểu
map
tương tự kiểu từ điển dict như trong Python - Kiểu ngày tháng
DateTime
- Kiểu
dynamic
là kiểu chấp nhận mọi kiểu dữ liệu khác, bạn có thể gán một giá trị là số, xâu, ngày tháng… cho biến kiểudynamic
Ngoài ra còn có một số kiểu khác nữa như Uri
hoặc Error
. Chúng ta sẽ lần lượt tìm hiểu về các kiểu dữ liệu trong Dart này trong các bài tiếp theo của loạt bài Tự học lập trình Dart này.
2.1. Kiểu số num
trong Dart
Kiểu số num
trong Dart bao gồm có kiểu số nguyên int
và kiểu số thực double
, bài chi tiết xin mời các bạn xem tại đây Kiểu số trong Dart/Flutter
2.2. Kiểu logic bool
trong Dart
2.3. Kiểu xâu String
trong Dart
3. Phân biệt const
và final
trong Dart
- Để khai báo một hằng số trong Dart, chúng ta sử dụng từ khóa
const
. - Để khai báo một biến chỉ nhận giá trị một lần và không thay đổi trong suốt chương trình, chúng ta sử dụng từ khóa
final
. Đương nhiên vẫn có thể sử dụng từ khóavar
hoặc khai báo định kiểu cho biến đó, nhưng cách này không tối ưu bằng cách sử dụngfinal
.
Một biến không thay đổi trong suốt chương trình thì có gì khác hằng số, và đâu là sự khác nhau của hai cách khai báo này? Bạn sẽ hiểu rõ hơn điều này khi chúng ta thảo luận về lớp class
ở những bài sau.
Có thể coi final
và const
đều biểu diễn cho các hằng số, nhưng const
là hằng số trong lúc biên dịch (compile-time) còn final
là hằng số và sẽ nhận được trong lúc chạy chương trình run-time
.
ở chỗ code vd ??=, các bạn nói int có giá trị mặc định là null, và có thể gán bằng ??= lần đầu, còn lần sau thì không được.
Bạn có chắc default value của int là null?? Và ví dụ của bạn là chính xác không ạ??
Ví dụ đó chính xác ở thời điểm viết bài bạn nhé. Ở thời điểm bây giờ Dart đã hỗ trợ null safety nên sẽ báo lỗi. Bạn xem bài nói về null sàety để rõ hơn nhé.
Mình vừa cập nhật lại bài viết theo null safety, bạn xem lại nhé.
chỗ “còn const là hằng số và sẽ nhận được trong lúc chạy chương trình run-time.” nó hơi sai sai, phải là final chứ ?
À, đúng rồi bạn. Để mình sửa lại.
sao cứ bấm vào bài là nó hiện link shopee khó chịu nhờ