Học nhanh ngôn ngữ Dart (Flutter) nhờ ngôn ngữ Kotlin (Phần 2 / 5)
Bài đăng này đã không được cập nhật trong 4 năm
1. Lời mở đầu
Series này được viết nhằm mục đích giúp những bạn đã hiểu biết về ngôn ngữ Kotlin hoặc Java có thể học nhanh ngôn ngữ Dart để code Flutter. Nếu bạn chưa đọc phần 1, bạn có thể đọc lại phần 1 tại đây
2. Toán tử
Đa số là giống Kotlin. Tuy nhiên có 1 vài điểm khác thì mình đã gạch đỏ và chú thích vào trong code.
Ngoài các toán tử trên ra thì:
- Toán tử gọi hàm (function call) cũng giống Kotlin là
()
. Ví dụ:print(3)
- Toán tử gọi member function hoặc property của object cũng là
.
. Ví dụ:student.goToSchool()
hoặcstudent.age
- Trong Dart chỉ có
as
chứ không cóas?
như Kotlin. - Toán tử
*
cũng có ích trong trường hợp mình cần sinh ra chuỗi string với độ dài mong muốn.print('a' * 3); // Output là: aaa
3. If else
Giống y Kotlin
if (3 > 2) {
print('Đúng');
print('Vào if')
} else if (4 > 5) {
print('Vào else if');
} else {
print('Vào else');
}
hoặc trong trường hợp trong block { }
chỉ có 1 câu lệnh:
if (3 > 2) print('Đúng');
4. For loop
Trông Kotlin có vẻ dễ nhớ cú pháp hơn. Còn Dart thì hơi khó nhớ nhỉ?. Nhưng đừng lo, vì qua phần 2 mình sẽ giới thiệu biểu thức lambda (lambda expression), dễ dùng hơn thế này nhiều . Biến list
trong ảnh bị lỗi do mình chưa khai báo biến list
đó. Qua phần 2 mình sẽ giới thiệu kiểu List
luôn nhé.
5. While loop
Giống y Kotlin:
while
while (!isDone()) {
doSomething();
}
do-while
do {
printLine();
} while (!atEndOfPage());
6. Break and continue
Công dụng của break
và continue
giống y Kotlin.
7. Switch and case
Chính là when
trong Kotlin
8. String template, String raw
String template thì giống hệt Kotlin. Nó cũng dùng $a
và ${a.func}
void main() {
var a = 3;
print('Giá trị của a là $a Kiểu của a là ${a.runtimeType}');
}
Để hiển thị String raw, Dart sử dụng double quote " "
(nháy kép)
print("Can't help falling in love with Dart");
Để ý, mình không sử dụng escape \
trước ký tự '
. Tức là nếu các bạn in câu trên mà sử dụng nháy đơn thì phải như thế này:
print('Can\'t help falling in love with Dart');
Multi-line string literal, Dart sử dụng 3 dấu nháy đơn '''
var s = '''A
multi-line
string''';
9. Exceptions
Giống Kotlin, tất cả các Exceptions trong Dart đều là unchecked exceptions, tức là bạn sẽ không bị ép phải try catch bắt cứ dòng code nào.
Dart cung cấp 2 lớp là Exception
(là class cha của tất cả các exception) và lớp Error
. Exception
và Error
không có ai kế thừa ai nhé. 2 thằng này về bản chất khác nhau hoàn toàn. Nếu như Exception
là những trường hợp ngoại lệ không lường trước và nên try/catch
những trường hợp này để đề phòng các case không mong muốn. Còn nếu app bạn gặp Error
thì chứng tỏ code bạn bị fail, code tệ, code lỗi và bạn buộc phải sửa chứ không nên try/catch
.
Cách throw một Exception cũng giống như Kotlin:
throw FormatException('Expected at least 1 section');
Ngoài ra, bạn có thể ném một Exception bất kỳ không cần biết class nào luôn:
throw 'Expected at least 1 section';
10. try / catch / finally
Tương đối giống Kotlin, chỉ có 2 điểm khác:
- Cách bắt cụ thể 1 exception nào đó:
on FormatException catch (e) { }
- Để throw lại một exception thì Dart cung cấp cho ta keyword là
rethrow
11. Class Null
Class Null
rất là đặc biệt, nó chỉ có 1 instance duy nhất chính là null
. Chính vì vậy mà so sánh null trong Dart sẽ có 2 kiểu thế này.
if (a is Null) // tuy nhiên cách viết này bị warning
hoặc
if (a == null) // cách viết này chuẩn
Khi khai báo biến mà chưa có giá trị khởi tạo thì biến đó sẽ có kiểu là Null
, cũng chính vì vậy mà ở bài 1 mình có nói nếu không có giá trị khởi tạo thì mọi biến đều có giá trị default là null
void main() {
var a;
print('Giá trị của a = $a');
print('Type của a là ${a.runtimeType}');
}
Output:
Giá trị của a = null
Type của a là Null
12.Toán tử 3 ngôi
Giống hệt Java. Toán tử này thì Kotlin không có.
var visibility = isPublic ? 1 : 0;
Giải thích: Nếu biến isPublic == null
thì biến visibility
được gán giá trị là 1
, ngược lại gán là 0
13. Toán tử null-aware
Toán tử ??
void main() {
var x; // biến x đang là null
print(x ?? 'x là null thì in vế sau ra');
}
Output:
x là null thì in vế sau ra
Toán tử này giống với toán tử Elvis ?:
trong Kotlin. Nghĩa là nếu x
là null
thì in vế sau ra
Toán tử ??=
void main() {
var x; // biến x đang là null
x ??= 'Nếu x bằng null thì gán x bằng String này';
print(x);
}
Output:
Nếu x bằng null thì gán x bằng String này
Nếu biến x
là null
thì gán giá trị bằng vế sau cho x
Toán tử ?.
?.
dùng để check null trước khi gọi function hoặc property giống Kotlin. Ví dụ student?.goToSchool()
hoặc student?.age
.
14. List và Array
Trong Dart nó gộp kiểu Array vs List lại chung một kiểu là List
. Cú pháp tạo ra một List
là [value, value, value, ...]
void main() {
// không sử dụng generic
var list = [1, 'a', true];
// sử dụng generic
var intList = <int>[1, 2, 3]; // một list object có kiểu int <=> listOf<Int>(1, 2, 3) trong Kotlin
var numList = <num>[1, 2, 3.333]; // một list object kiểu num
var dynamicList = <dynamic>[1, 'a', true]; // một list object có type bất kỳ
}
Hàm add, set, remove và get của List
void main() {
var intList = <int>[1, 2, 3]; // một list object có kiểu int
// add phần tử
intList.add(4);
// update phần tử tại index
intList[0] = 5;
// remove phần tử tại index
intList.removeAt(0);
// get phần tử tại index
var b = intList[0];
}
15. Collection if, collection for
Collection if này Kotlin không có hỗ trợ.
var nav = [
'Home',
'Furniture',
'Plants',
if (isMine) 'Outlet'
]; // chỉ khi biến isMine == true thì 'Outlet' mới được add vào list và ngược lại
Collection for này Kotlin cũng không có hỗ trợ.
var listOfInts = [1, 2, 3];
var listOfStrings = [
'số 0',
for (var i in listOfInts) 'số $i'
];
print(listOfStrings);
Output:
[số 0, số 1, số 2, số 3]
Nó duyệt hết phần tử trong list listOfInts
rồi add vào list listOfStrings
16. Toán tử spread (spread operator và null-aware spread operator)
Toán tử spread ...
này Kotlin không có, nó giúp mình addAll một list B vào một list A một cách nhanh chóng.
var listA = [1, 2, 3];
var listB = [0, ...listA]; // addAll tất cả phần tử của listA vào listB
print(listB); // in ra: [0, 1, 2, 3]
Tương tự null-aware spread operator ...?
cũng giống vậy nhưng khác ở chỗ nó sẽ check null trước khi addAll.
var listA; // listA đang null
var listB = [0, 1, ...?listA]; // nên listA sẽ không được addAll vào listB
print(listB); // in ra: [0, 1]
17. Immutable và Mutable List
Thật sự trong Dart không tồn tại khái niệm Immutable List. Nó chỉ có một kiểu gọi là List
, mà kiểu này cho phép add
, set
và remove
phần tử ra khỏi list nên nó là kiểu mutable. Tuy nhiên cũng có 3 cách để lách luật tạo ra một immutable list :v
Cách 1: sử dụng List.unmodifiable
truyền vào 1 biến kiểu List
var a = List.unmodifiable(<int>[1, 2]);
a.add(3);
Nếu immutable list Kotlin nó sẽ báo lỗi compile ngay dòng code a.add(3)
và tất nhiên bạn sẽ không thể chạy được chương trình thì ở Dart hơi khác một chút, nó không báo lỗi compile nhưng khi run nó sẽ xảy ra lỗi ở Runtime:
Unsupported operation: Cannot add to an unmodifiable list
Ngoài hàm add ra, thì hàm set, remove cũng sẽ xảy ra Exception:
var a = List.unmodifiable(<int>[1, 2]);
a.add(3); // throw Exception
a[0] = 1; // throw Exception
a.removeAt(0); // throw Exception
Cách 2 và 3: sử dụng từ khóa const
// Cách 2
var a = const [1, 2, 3];
a.add(4); // throw Exception
a[1] = 1; // throw Exception
a.removeAt(0); // throw Exception
// Cách 3
const b = [1, 2, 3];
b.add(4); // throw Exception
b[1] = 1; // throw Exception
b.removeAt(0); // throw Exception
18. Set
Set chứa những phần tử không duplicate. Cú pháp tạo ra một Set
là {value, value, value, ...}
void main() {
// không sử dụng generic
var set = {1, 'a', true};
// sử dụng generic
var intSet = <int>{1, 2, 3, 2, 3, 4}; // <=> setOf<Int>(1, 2, 3, 2, 3, 4) trong Kotlin
print(intSet); // in ra: {1, 2, 3, 4}
}
Set cũng support spread operator ...
and the null-aware spread operator ...?
19. Map
Cú pháp tạo ra một Map
là: {key: value, key: value, key: value, ....}
void main() {
// không sử dụng generic
var map = {1: 3, 'a': 3.3, 0.333: true};
// sử dụng generic
var genericMap = <int, dynamic>{1: 3, 2: 3.3, 3: true};
print(genericMap); // in ra: {1: 3, 2: 3.3, 3: true}
// Hàm put
genericMap[5] = 'abc';
// Hàm get
var b = genericMap[5];
print(b); // in ra: abc
}
Chú ý: Vì cả Set
và Map
đều dùng dấu { }
cho nên khi ta viết code thế này nó sẽ suy đoán kiểu ra kiểu Map
:
var names = {}; // Tạo ra một Map rỗng, ko phải Set
Nếu chúng ta muốn tạo ra một Set rỗng có thể làm như sau:
var names = <String>{};
// hoặc
Set<String> otherNames = {};
Kết luận
Như vậy là chúng ta đã đi được hơn nửa chặng đường rồi . Hy vọng các bạn tiếp tục theo dõi những phần tiếp theo
Tham khảo: https://dart.dev/guides
Đọc tiếp phần 3: Học nhanh ngôn ngữ Dart (Flutter) nhờ ngôn ngữ Kotlin (Phần 3)
All rights reserved