Những điểm đánh dấu khi tìm hiểu về Dart
TIL
720
dart
5
White

Trần Đức Tâm viết ngày 17/12/2018

Những điểm đánh dấu khi tìm hiểu về Dart

Mình cùng với ông anh chơi chung nó cùng chạy đua một thử thách xem ai học Flutter nhanh nhất. Sau đây là thành quả sau ba đêm cuối tuần cày Dart lang là ngôn ngữ được sử dụng trong Flutter. Để đọc hiểu bài này, bạn cần phải có kinh nghiệm code một hoặc vài ngôn ngữ lập trình trước đó. Bài viết không phải bài hướng dẫn mà chỉ là phần note lại các điểm được mình cho là quan trọng sau khi đọc docs của Dart. Những phần không quan trọng mặc định bỏ qua.

Trong Dart mọi thứ đều là object

Trong Dart mọi thứ đều là object. Đã là Object thì luôn phải là instance của một class nào đó. Chính vì tất cả đều là object nên dù là số, chữ hay bất kể loại kiểu dữ liệu nào thì giá trị mặc định của nó đều là null. Nhờ vậy, mọi biến số trong Dart đều là reference type. Cũng chính thế mà Dart có một loại biến dynamic chấp nhận mọi kiểu dữ liệu.

Non-dynamic data type

main () {
  var x = 1;
  x = 1.5;  // Error: A value of type 'double' can't be assigned to a variable of type 'int'
}

Dynamic data type

main () {
  dynamic x = 1;
  x = 1.5;
}

Toán tử Null-aware

Vì giá trị mặc định của mọi thứ trong Dart đều là null. Điều này đi ngược lại xu thế phát triển của xã hội. Chính vì vậy mà Dart có một loạt toán tử Null-aware để đảm bảo null safe trong quá trình thực thi code.

Ví dụ về Null-aware

void main() {
  print(null ?? 'Trả về chính nó nếu khác null hoặc trả về dòng này');

  var x = null;
  x ??= 'Syntax sugar của `x = x ?? "Viết gì vào đây bây giờ"`';
  print(x);

  var isNull = null;
  print(isNull?.foo()); // Nếu null thì không thực hiện foo() nữa mà trả về `null`
}

Một trong những lưu ý có liên quan đó là mọi hàm trong Dart đều trả về dữ liệu. Mặc định trả về của một hàm cũng là null.

Có năm cách để đánh dấu khai báo một biến/hằng số trong Dart

  • Cách đầu tiên là đặt kiểu dữ liệu trước tên biến. Biến sẽ chỉ được khai báo một lần và tất cả mọi lần thay đổi dữ liệu biến đều phải giữ nguyên kiểu dữ liệu cũ.
  • Sử dụng var giúp cho biến dù được khai báo một lần và không thể thay đổi kiểu dữ liệu. Tuy nhiên sau lần nhận dữ liệu đầu tiên, biến mới được xác định kiểu dữ liệu của bản thân.
  • Sử dụng dynamic giúp cho biến dù được khai báo một lần nhưng muốn thay đổi dữ liệu và kiểu dữ liệu bao nhiêu lần cũng được.
  • finalconst là hai từ khóa dễ nhầm cần được nói riêng.

Một biến được khai báo là final sẽ trở thành hằng số chỉ có thể được truyền dữ liệu một lần. Tuy nhiên dữ liệu vẫn có thể tự thay đổi các giá trị thuộc tính bên trong nó.

Ví dụ về final

class A {
  var a = 'dummy';
}

main() {
  final a = A();
  assert(a.a == 'dummy');
  a.a = 'new';
  assert(a.a == 'new');
  a = A();  // Error: 'a', a final variable, can only be set once
}

Một biến được khai báo là const sẽ trở thành hằng số được build thành các literal tại thời điểm compile time. Điều này nghĩa là toàn bộ dữ liệu được truyền vào đều bị đóng băng và không thể thay đổi. Và vì được build vào thời điểm compile time dẫn đến phần tử của object thì không thể là const được. Một biến muốn được khai báo là const thì buộc phải static hoặc là top-level variable.

Ngoài ra, const cũng có thể được dùng cho việc khai báo cho khối dữ liệu truyền vào. Lí do thì nó rất là buồn cười, để tôi chỉ các bạn thấy.

Ví dụ về const

main() {
  var a = const [];  // (1) a có thể được đổi thành giá trị khác ngoài một list rỗng ([])
  final b = const [];  // (2) b chính là const chứ còn gì nữa
  const c = const [];  // (3) c được khuyến cáo là viết thừa
}

Trường hợp (2) chính là lí do. Vì một phần tử của object không thể là const vì lí do tại thời điểm compile time thì nó chưa tồn tại. Vậy cách để thực hiện việc này là tạo ra một khối dữ liệu const được build tại thời điểm compile time là list rỗng ([]). Đến lúc xuất hiện object thì ta đặt phần tử mong muốn thành final, truyền cho nó khối dữ liệu ([]) và a lê hấp nó đã biến thành một phần tử const.

Dart hỗ trợ UTF-32

Vì mặc định một kí tự Unicode được biểu diễn như regex sau: \\u[0-9a-f]{4} ví dụ \u09af. Điều này cho thấy là một kí tự chỉ biểu diễn được tối đa là 4 kí tự hex có tổng là 16 bits. Vậy để biểu diễn được UTF-32, Dart đưa ra một cú pháp được gọi là Runes có các biểu diễn như regex sau: \\u\{[0-9a-f]{1, 8}\} ví dụ \u09af, \u09, \u09affa90

Dart hỗ trợ đa kế thừa

Về mặt cú pháp thì Dart vẫn chỉ có một kế thừa duy nhất, tuy nhiên Dart lại hỗ trợ kĩ thuật mixins thông qua từ khóa with. Việc này dẫn đến diamon problem là việc khi kế thừa lại có ít nhất hai supper class có ít nhất một method cùng tên và cùng danh sách tham số truyền vào. Điều này gây ra là ở phía sub-class khi gọi đến method đó thì không biết chọn cái nào. Với Dart, câu trả lời là của supper class cuối cùng được khai báo. Vậy điểm lưu ý là thứ tự khai báo rất quan trọng trong Dart.

Dart không có accept modifier

Trong Dart thì cùng một file.Dart với nhau thì mọi thứ là public. Còn với những tài nguyên thuộc về file.Dart khác. Tên biến có bắt đầu bởi kí tự _ thì được coi là private ở mức độ packages/files/libraries.

Vậy nếu không có private, làm sao triển khai được singleton? Dart lại sinh ra một keyword gọi là factory. Với factory ta sẽ triển khai được một singleton như sau:

Giới thiệu về singleton trong Dart

class Singleton {
  static final Singleton _singleton = new Singleton._internal();

  factory Singleton() {
    return _singleton;
  }

  Singleton._internal();
}

main() {
  var s1 = new Singleton();
  var s2 = new Singleton();
  assert(identical(s1, s2));
  assert(s1 == s2);
}

Tham số dạng positional và named trong Dart

Dart đưa ra hai khái niệm là positionalnamed tham số. Hai khái niệm này khác nhau ở điểm. positional cho phép ta đặt giá trị mặc định hoặc không (mặc định là null) cho tham số truyền vào. Từ đó, ta có thể thêm bớt số lượng tham số trong lời gọi hàm. Ràng buộc của positional là vị trí khai báo phải nằm cuối cùng trong phần khai báo. Danh sách positional trong lời gọi hàm không được thay đổi thứ tự.

Ví dụ về positional

getNumber(String one, String two, [int three, String four]) {
    return '$one, $two, $three, $four';
}

main() {
  assert(getNumber('1', '2') == '1, 2, null, null');
  assert(getNumber('1', '2', 3) == '1, 2, 3, null');
  assert(getNumber('1', '2', 3, '4') == '1, 2, 3, 4');
}

named thì linh hoạt hơn khi chấp nhận không theo thứ tự khi gọi hàm miễn là thỏa mãn việc tên tham số được chỉ rõ. Lưu ý là không thể có cả positional lẫn named trong cùng một method.

Ví dụ về named

getNumber(String one, String two, {int three, String four}) {
    return '$one, $two, $three, $four';
}

main() {
  assert(getNumber('1', '2') == '1, 2, null, null');
  assert(getNumber('1', '2', three: 3) == '1, 2, 3, null');
  assert(getNumber('1', '2', four: '4') == '1, 2, null, 4');
}

Đại khái note lại là vậy

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Trần Đức Tâm

6 bài viết.
133 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
56 9
Phần I.I Machine Learning là gì? TL;DR Mình nghiên cứu Machine Learning(Link) bắt đầu từ khoảng một năm về trước, mất khoảng sáu tháng để tự luyệ...
Trần Đức Tâm viết 2 năm trước
56 9
White
40 9
$ Flutter và Flutter Architecture Components Chapter 1] Ngụp lặn với Flutter (Dive to Flutter) Sau sáu tháng cày cuốc tiếng Nhật, năm mới, thử th...
Trần Đức Tâm viết 6 tháng trước
40 9
White
37 13
Phần I.2 Tensorflow và bài toán Hồi quy đơn giản đầu tiên TL;DR Qua bài viết trước, chúng ta đã biết được đến sự tồn tại của một vài khái niệm cơ ...
Trần Đức Tâm viết 2 năm trước
37 13
Bài viết liên quan
White
1 0
Control flow statements Anh em có thể tham khảo tại (Link). Vì phần này khá cơ bản và giống Java, không có gì đặc biệt nên mình sẽ bỏ qua. Throw...
ngohado viết hơn 1 năm trước
1 0
White
40 9
$ Flutter và Flutter Architecture Components Chapter 1] Ngụp lặn với Flutter (Dive to Flutter) Sau sáu tháng cày cuốc tiếng Nhật, năm mới, thử th...
Trần Đức Tâm viết 6 tháng trước
40 9
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
6 bài viết.
133 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!