Contents
Chào mừng bạn đến với Fx Studio. Chuyến du lịch Dart Tour của chúng ta lại tiếp tục với một chủ đề mới. Chủ đề lần này là Data Type, hay Kiểu dữ liệu được sử dụng trong ngôn ngữ lập trình Dart. Bên cạnh đó, bạn sẽ tìm hiểu thêm các toán tử liên quan tới các kiểu dữ liệu và biến đổi dữ liệu trong Dart.
Nếu mọi việc đã ổn rồi, thì …
Bắt đầu thôi!
Chuẩn bị
Về mặt công cụ editor thì khá đơn giản:
- TextEditor
- Visual Studio Code (nên dùng)
Hoặc bạn vào trang https://dartpad.dev/ để tiến hành code luôn. Khá là giống với Playground của Swift.
Để bắt đầu tìm hiểu về Data Type, bạn tham khảo lại bài viết Variables & Constant trong Dart trước nhóe.
Data Type
Ngôn ngữ Dart cũng giống như các ngôn ngữ lập trình khác, Kiểu dữ liệu (type) sẽ giúp trình biên dịch xác định và cấp phát bộ nhớ cho chương trình với cấu trúc dữ liệu phù hợp.
Chúng ta sẽ có một số kiểu dữ liệu cơ bản mà Dart cung cấp sẵn như sau:
- Number: với các đại diện cho kiểu dữ liệu là số. Bao gồm:
int
double
num
- String: đại diện cho các kí tự hoặc một chuỗi kí tự trong Dart
string
- Boolean: đại cho kiểu dữ liệu logic (đúng hoặc sai) trong Dart
bool
- List: đại diện cho kiểu dữ liệu là mãng trong Dart
- Map: đại diện cho kiểu dữ liệu ánh xạ hoặc từ điển trong Dart
- Set: đại diện cho kiểu dữ liệu tập hợp
- …
Ngoài ra, ta sẽ có thể 2 kiểu dữ liệu khá là đặc biệt nữa mà được Dart cung cấp cho. Đó là:
- Object Type
- Dynamic Type
Chúng ta sẽ lần lượt tìm hiểu chúng ở các phần dưới đây.
Type inference
Trong bài viết trước, bạn đã tìm hiểu sơ qua kiểu nội suy (hay nội suy) này rồi. Và chúng ta sẽ đi vào chi tiết nhiều hơn một tí với nó nha.
Annotating variables explicitly
Điều này có nghĩa là Dart khuyên bạn:
Hãy nên khai báo càng chi tiết càng tốt về kiểu dữ liệu cho một biết.
Trong các phần mềm IDE sẽ báo là cần chú thích kiểu rõ hơn. Ví dụ code như sau:
int myInteger = 999; double myDouble = 876.5;
Khi khai báo các biến như vậy, mọi người sẽ hiểu được kiểu dữ liệu đó là gì. Giúp cho việc tiếp cận code của dự án sẽ đơn giản hơn.
Creating constant variables
Ở bài viết trước, mình đã nói khái niệm này hơi buồn cười rồi.
Hằng số = Biến số với giá trị không đổi
Vẫn giữ cách khai báo như trên, bạn chỉ cần thêm từ khoá const
hay final
là ổn.
const int myInteger = 999; const double myDouble = 876.5;
Thử với từ khóa final
nhóe!
final int myInteger = 999; final double myDouble = 876.5;
Letting the compiler infer the type
Và tất nhiên, Dart đủ thông minh để có thể nội suy ra được type
gì, với giá trị bạn cung cấp ban đầu cho biến/hằng. Do đó, bạn có thể lượt bỏ đi các kiểu dữ liệu ở phần khai báo.
Tuy nhiên, áp dụng cho các kiểu dữ liệu cơ bản và mặc định. Ví dụ: 10 sẽ là int, 3.14 là Double chứ không phải Float.
Ví dụ:
const myInteger = 999; const myDouble = 876.5;
Checking
Để kiểm tra kiểu dữ liệu của một biến là kiểu gì, thì bạn có thể dùng toán tử is
. Ta tham khảo ví dụ sau nhóe!
num myNumber = 3.14; print(myNumber is double); //true print(myNumber is int); //false
Toán tử is
kiểu dữ liệu phía sau, thì kết quả sẽ là một boolean. Cái này dùng lúc run-time nhoé.
Cuối cùng, toán tử runtimeType
là cách để in ra kiểu dữ liệu hiện tại của biến. Áp dụng có một số kiểu dữ liệu động mà Dart cung cấp. Ta xem tiếp ví dụ nhóe!
print(myNumber.runtimeType);
Nhẹ người chưa nào!
Type conversion
Tiếp theo là loại chuyển đổi. Chắc bạn sẽ suy nghĩ đây là loại kiểu dữ liệu đa năng rồi. Tuy nhiên, xem ví dụ sau trước nha:
var integer = 100; var decimal = 12.5; integer = decimal;
Tất nhiên, Dart sẽ báo lỗi. Vì nó làm cho chương trình không an toàn. Khi bạn cố gán giá trị của một kiểu dữ liệu khác cho một kiểu dữ liệu khác.
Muốn fix, thì hãy sử dụng vài toán tử mà bạn có thể nghĩ ra để chuyển đổi kiểu dữ liệu cho phù hợp. Ví dụ cho trường hợp trên là:
integer = decimal.toInt();
Bạn có thể tự mò với cú pháp .to
, rồi thêm gì gì đó phía sau nhóe. Ví dụ: toInt, toDouble, toString …. Như vậy, cả làng đều vui rồi.
Operators with mixed types
Tiếp tục, cuộc vui vẫn còn khi bạn có thể sử dụng vài toán tử để trộn các kiểu dữ liệu với nhau:
const hourlyRate = 19.5; const hoursWorked = 10; const totalCost = hourlyRate * hoursWorked;
Trong đó:
hourlyRate
làdouble
&hoursWorked
làint
- Nhân chúng với nhau, thì sự lựa chọn kiểu dữ liệu an toàn nhất cho
totalCost
làdouble
Và khi bạn muốn đưa totalCost
về kiểu int
thì có thể dùng .toInt()
.
const totalCost = (hourlyRate * hoursWorked).toInt();
Tuy nhiên, chương trình sẽ báo lỗi. Vì bạn không thể xác định kiểu của totalCost
ngay thời điểm hiện tại. Chúng cần phải được tính toán ra. Do đó, đổi từ const
thành final
là ổn nhất.
final totalCost = (hourlyRate * hoursWorked).toInt();
Bạn đã thấy sự nhau giữa 2 từ khóa
const
vàfinal
rồi đây!
Ensuring a certain type
Đôi khi chúng ta cần xác định một kiểu dữ liệu không đổi, khi bạn lại gán cho nó một giá trị có kiểu dữ liệu khác. Điều bạn có thể nghĩ ra như sau:
Bắt đầu khai báo một hằng số:
const wantADouble = 9;
Như trên, 100% hằng số này là kiểu int
. Bạn muốn đổi nó sang double
, thì như trên sẽ là như sau:
final actuallyDouble = 9.toDouble();
Nhìn sơ qua, thì nó cũng đúng. Nhưng nhìn kĩ, thì nó quá ngáo luôn. Thôi bạn hãy về chánh đạo như sau:
const double actuallyDouble = 9;
Hãy khai báo đầy đủ và rõ ràng là tốt nhất.
Hoặc đơn giản, bạn có thể cung cấp cho nó giá trị mà mang ý nghĩa biểu thị cho kiểu dữ liệu double
.
const wantADouble = 9.0;
Casting down
Việc mà biến đổi từ kiểu dữ này thành kiểu dữ liệu khác. Hoặc các kiểu dữ liệu chung về một kiểu dữ liệu con cụ thể nào đó. Được gọi là
casting type
Ví dụ: bạn có 1 biến kiểu num
là một kiểu số chung chung.
num someNumber = 333; print(someNumber.isEven);
int
hay double
. Muốn về 1 kiểu con chính xác, thì bạn hãy dùng từ khoá as
. Xem ví dụ:final someInt = someNumber as int; print(someInt.isEven);
Công việc với as
được gọi là casting type. Tuy nhiên, việc ép kiểu này chỉ được ép xuống thôi, chứ không thể ép lên. Ví dụ, bạn ép kiểu từ int
lên double
như sau:
num someNumber = 3; final someDouble = someNumber as double;
Thì sẽ bị báo lỗi. Tốt nhất hãy dùng đến .toDouble()
. Hi vọng bạn đã hiểu hơn một chút về kiểu dữ liệu và các vấn đề xoay quanh việc chuyển đổi kiểu dữ liệu.
Strings
Trong Dart, string
là một chuỗi giữ các kí tự với mã UTF-16
. Chúng nằm trong 2 dấu ' '
hoặc " "
. Ví dụ nhoé:
var s1 = 'Single quotes work well for string literals.'; var s2 = "Double quotes work just as well."; var s3 = 'It\'s easy to escape the string delimiter.'; var s4 = "It's even easier to use the other delimiter.";
Hoặc từ một giá trị là số, bạn có thể chuyển đổi nó sang String một cách nhanh chóng bằng toán tử .toString()
Unicode
Với việc trang bị bộ mã Unicode cho String, thì đem lại cho Dart khá nhiều sức mạnh. Đủ để mô tả toàn bộ kí tự trên thế giới này.
Bạn có thể đọc thêm về Unicode tại website chính thức là unicode.org.
Bao gồm các:
- Character truyền thống
- Các kí tự số
- Kí tự đặc biệt
- Emojis
- …
Cách để xem các ký tự trong chuỗi thành mã của nó với bảng mã Unicode, thì sử dụng .codeUnits
. Ví dụ:
var salutation = 'Hello!'; print(salutation.codeUnits);
Kết quả của bạn sẽ là:
[72, 101, 108, 108, 111, 33]
Áp dụng được cho các ký tự đặc biệt và emojis nha.
Strings and characters
Ta có một ví dụ sau:
var greeting = 'Hello, Dart!'; print(greeting);
Giúp bạn dễ phân biệt ra giữa 2 khái niệm trên. Ta hãy phân tích tiếp nhóe!
greeting
là kiểustring
Hello, Dart
là một chuỗi ký tự (string literal)
Và khi bạn gán một biến String bằng một chuỗi kí tự khác, có nghĩa là bạn loại bỏ chuỗi cũ đi và thay bằng chuỗi mới hoàn toàn.
Nếu bạn nghĩ việc khai báo như thế này thì sẽ có 1 Character.
var name = 'a'
Thì với một ký tự, nhưng Dart sẽ hiểu là một chuỗi kí tự với số lượng là 1
.
Single-quotes vs. double-quotes
Để tạo ra một chuỗi kí tự bạn có thể dùng cả 2 dấu '
và "
vẫn được. Tất cả đều vẫn okay. Tuỳ thuộc vào thói quen trước đây của bạn với các ngôn ngữ khác. Ví dụ nhóe!
var s1 = 'Hôm nay trời đẹp lên cao'; var s2 = "Tôi buồn không hiểu vì sao tôi";
Multi-line strings
Khi bạn muốn mô tả một đoạn văn hay nhiều dòng, thì bạn sử dụng '''
hay """
để bắt đầu nhập 1 đoạn văn bản.
3 dấu liên tiếp
Ví dụ:
var s1 = ''' You can create multi-line strings like this one. '''; var s2 = """This is also a multi-line string.""";
Combine String
Bạn có 2 String và muốn tạo ra một String mới từ chúng, bạn có thể dùng toán tử +
. Ví dụ như sau:
var firstname = 'Fx';
var lastname = 'Studio';
var fullname = firstname + lastname;
print(fullname); //FxStudio
Bạn có thể thêm trực tiếp 1 chuỗi kí tự vẫn được. Xem tiếp ví dụ:
var fullname = firstname + ' ' + lastname;
Interpolation
Phép nội suy từ giá trị của biến trong một chuỗi ký tự với toán tử $
. Bạn có thể chèn một String này vào trong một String khác. Chúng ta sử dụng toán tử $
phía trước và tên biến ở phía sau:
var age = 18;
var hello = 'Hello, I am $fullname . I am $age year olds';
Không chỉ $
cho biến String và các biến với các kiểu dữ liệu khác thì đều vẫn được.
Đây là cách bạn chèn thêm giá trị của một biến vào một chuỗi string.
StringBuffer
Dart cung cấp cho chúng ta một kiểu là StringBuffer
, để giúp bạn tạo ra một String bằng cách thêm nhiều chuỗi kí tự vào. Xem ví dụ sau nhóe!
final message = StringBuffer();
message.write('Hello');
message.write(' my name is ');
message.write('Fx');
message.toString();
// "Hello my name is Fx"
Bạn sử dụng .write
để thêm vào. Và lúc nào xuất ra một chuỗi string, thì dùng .toString()
.
Raw String
Bạn hãy thử thực thi đoạn code ví dụ này nhóe!
var s = 'In a raw string, not even \n gets special treatment.';
print(s);
Kết quả là sẽ có 2 dòng được in ra, vì ký tự \n
là enter. là việc tạo ra một dòng mới.
Trong String, chúng ta có rất nhiều ký tự đặt biệt như vậy. Nên để in ra được giá trị thô raw string
, thì hãy bắt đầu bằng kí tự r'....'
cho string.
Ví dụ:
var s = r'In a raw string, not even \n gets special treatment.';
Tính ra là cũng khá mợt mỏi với đám String này. Ahuhu!
Object & Dynamic Types
Ngôn ngữ Dart được phát triển để giải quyết các vấn đề tồn tại trong Javascript. Mà Javascript được xem là một ngôn ngữ động. Linh hoạt trong kiểu dữ liệu của các biến. Và cũng vì vậy,
Dart có thêm một kiểu dữ liệu động nữa. Cũng khá thú vị.
Bạn sẽ dùng từ khoá dynamic
để khai báo 1 biến với kiểu dữ liệu động nhóe! Xem ví dụ sau:
dynamic myVariable = 42; myVariable = "hello";
Trong đó:
- Lúc khai báo ban đầu thì
myVariable
là kiểuint
- Sau đó được gán bằng
hello
thìmyVariable
là kiểustring
Hoặc bạn sử dụng var
và không cung cấp giá trị ban đầu cho biến, thì Dart sẽ mặc định cho biến đó là kiểu dữ liệu động.
var myVariable2; myVariable2 = "hello"; //OK myVariable2 = 54; //OK
Cuối cùng, bạn có thể dụng kiểu là Object?
vẫn đảm bảo được kiểu dữ liệu linh hoạt của biến.
Object? myVariable3 = 42; myVariable3 = 'hello'; // OK
Cũng tương tự như Optional của Swift và Any cho kiểu dữ liệu bất kì. Qua trên, bạn có tới 3 cách để khai báo 1 biến với kiểu dữ liệu động.
Lời khuyên chân thành là đừng chơi dại mà hối hận không kịp nha.
Tạm kết
- Tìm hiểu về các kiểu dữ liệu cơ bản mà Dart cung cấp
- Các vấn đề nội suy kiểu dữ liệu trong Dart
- Các cách chuyển đổi kiểu dữ liệu với nhau
- String và các vấn đề liên quan
- Kiểu dữ liệu động trong Dart
Okay! Tới đây, mình xin kết thúc bài viết về Data Type trong series Dart Tour. Nếu có gì thắc mắc hay góp ý cho mình thì bạn có thể để lại bình luận hoặc gởi email theo trang Contact.
Cảm ơn bạn đã đọc bài viết này!
Related Posts:
Written by chuotfx
Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!
Leave a Reply Cancel reply
Fan page
Tags
Recent Posts
- Charles Proxy – Phần 1 : Giới thiệu, cài đặt và cấu hình
- Complete Concurrency với Swift 6
- 300 Bài code thiếu nhi bằng Python – Ebook
- Builder Pattern trong 10 phút
- Observer Pattern trong 10 phút
- Memento Pattern trong 10 phút
- Strategy Pattern trong 10 phút
- Automatic Reference Counting (ARC) trong 10 phút
- Autoresizing Masks trong 10 phút
- Regular Expression (Regex) trong Swift
You may also like:
Archives
- September 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (4)
- April 2024 (2)
- March 2024 (5)
- January 2024 (4)
- February 2023 (1)
- January 2023 (2)
- November 2022 (2)
- October 2022 (1)
- September 2022 (5)
- August 2022 (6)
- July 2022 (7)
- June 2022 (8)
- May 2022 (5)
- April 2022 (1)
- March 2022 (3)
- February 2022 (5)
- January 2022 (4)
- December 2021 (6)
- November 2021 (8)
- October 2021 (8)
- September 2021 (8)
- August 2021 (8)
- July 2021 (9)
- June 2021 (8)
- May 2021 (7)
- April 2021 (11)
- March 2021 (12)
- February 2021 (3)
- January 2021 (3)
- December 2020 (3)
- November 2020 (9)
- October 2020 (7)
- September 2020 (17)
- August 2020 (1)
- July 2020 (3)
- June 2020 (1)
- May 2020 (2)
- April 2020 (3)
- March 2020 (20)
- February 2020 (5)
- January 2020 (2)
- December 2019 (12)
- November 2019 (12)
- October 2019 (19)
- September 2019 (17)
- August 2019 (10)