KIẾN THỨC CƠ BẢN VỀ DART (PHẦN 4)

by doanquyet
667 views

Collections

Bộ sưu tập rất hữu ích để nhóm dữ liệu liên quan. Dart bao gồm một số loại bộ sưu tập khác nhau, nhưng hướng dẫn này sẽ bao gồm hai loại phổ biến nhất: List và Map.

Lists

Lists trong Dart tương tự như arrays trong các ngôn ngữ khác. Bạn sử dụng chúng để duy trì một danh sách các giá trị có thứ tự. Danh sách dựa trên 0, vì vậy mục đầu tiên trong danh sách ở chỉ mục 0:

Dưới đây là danh sách các món tráng miệng khác nhau:

List desserts = ['cookies', 'cupcakes', 'donuts', 'pie'];

Bạn đặt các phần tử của danh sách trong dấu ngoặc vuông [ ] . Bạn sử dụng dấu phẩy để phân tách các phần tử.

Ở đầu dòng, bạn có thể thấy rằng loại là List. Bạn sẽ nhận thấy không có loại nào được bao gồm. Dart suy luận rằng danh sách có loại List

Đây là danh sách các số nguyên:

final numbers = [42, -1, 299792458, 100];

Nhập numbers vào DartPad và bạn sẽ thấy rằng Dart nhận dạng loại List của int.

Làm việc với các phần tử trong List

Để truy cập các phần tử của danh sách, hãy sử dụng ký hiệu chỉ số con bằng cách đặt số chỉ mục giữa dấu ngoặc vuông sau tên biến danh sách. Ví dụ:

final firstDessert = desserts[0];
print(firstDessert); // cookies

Vì chỉ số danh sách dựa trên số không, desserts[0]là phần tử đầu tiên của danh sách.

Thêm và xóa các phần tử với add và remove tương ứng:

desserts.add('cake');
print(desserts); 
// [cookies, cupcakes, donuts, pie, cake]

desserts.remove('donuts');
print(desserts); 
// [cookies, cupcakes, pie, cake]

Chạy mã để xem kết quả.

Trước đó, bạn đã học về forvòng lặp. for-inVòng lặp của Dart hoạt động đặc biệt tốt với các danh sách. Hãy thử nó:

for (final dessert in desserts) {
  print('I love to eat $dessert.');
}
// I love to eat cookies.
// I love to eat cupcakes.
// I love to eat pie.
// I love to eat cake.

Bạn không cần sử dụng chỉ mục. Dart chỉ lặp qua mọi phần tử của dessertsvà gán nó mỗi lần cho một biến có tên dessert.

Maps

Khi bạn muốn một danh sách các giá trị được ghép nối, Map là một lựa chọn tốt. Dart Map tương tự như dictionaries  trong Swift và maps trong Kotlin.

Đây là một ví dụ về map trong Dart:

Map<String, int> calories = {
  'cake': 500,
  'donuts': 150,
  'cookies': 100,
};

Bạn bao quanh Maps bằng dấu ngoặc nhọn { }. Sử dụng dấu phẩy để phân tách các phần tử của bản đồ.

Các phần tử của bản đồ được gọi là cặp khóa-giá trị , trong đó khóa ở bên trái dấu hai chấm và giá trị ở bên phải.

Bạn tìm thấy một giá trị bằng cách sử dụng khóa để tra cứu nó, như sau:

final donutCalories = calories['donuts'];
print(donutCalories); // 150

Từ khóa 'donuts'nằm trong dấu ngoặc vuông sau tên bản đồ. Trong trường hợp này, nó ánh xạ tới một giá trị 150.

Nhập donutCalories vào DartPad và bạn sẽ thấy rằng kiểu được suy luận thì int? đúng hơn int. Đó là bởi vì, nếu một bản đồ không chứa khóa mà bạn đang tìm kiếm, nó sẽ trả về một giá trị null.

Thêm một phần tử mới vào bản đồ bằng cách chỉ định khóa và gán cho nó một giá trị:

calories['brownieFudgeSundae'] = 1346;
print(calories);
// {cake: 500, donuts: 150, cookies: 100, brownieFudgeSundae: 1346}

Chạy mã đó và bạn sẽ thấy bản đồ được in ở định dạng ngang với món tráng miệng mới của bạn ở cuối.

Functions

Các hàm cho phép bạn đóng gói nhiều dòng mã liên quan vào một nội dung duy nhất. Sau đó, bạn triệu hồi hàm để tránh lặp lại những dòng mã đó trong ứng dụng Dart của mình.

Một hàm bao gồm các phần tử sau:

  • Kiểu trả về
  • Tên chức năng
  • Danh sách tham số trong ngoặc đơn
  • Nội dung hàm được đặt trong dấu ngoặc

Defining Functions

Đoạn mã bạn đang chuyển thành một hàm nằm trong dấu ngoặc nhọn. Khi bạn gọi hàm, bạn truyền vào các đối số phù hợp với loại tham số của hàm.

Tiếp theo, bạn sẽ viết một hàm mới trong DartPad sẽ kiểm tra xem một chuỗi đã cho có phải là Banana hay không :

bool isBanana ( String fruit) {
   return fruit == 'banana' ; 
}

Hàm sử dụng return để trả về kiểu bool. Đối số bạn truyền vào hàm sẽ xác định bool.

Hàm này sẽ luôn trả về cùng một kiểu giá trị cho bất kỳ đầu vào nhất định nào. Nếu một hàm không cần trả về giá trị, bạn có thể đặt kiểu trả về void.  main làm điều này, chẳng hạn.

Làm việc với các Function

Bạn có thể gọi hàm bằng cách truyền vào một chuỗi. Sau đó, bạn có thể chuyển kết quả của cuộc gọi đó tới print:

void main() {
  var fruit = 'apple';
  print(isBanana(fruit)); // false
}

Các Function lồng vào nhau

Thông thường, bạn xác định các hàm bên ngoài các hàm khác hoặc bên trong các lớp Dart. Tuy nhiên, bạn cũng có thể lồng các hàm Dart. Ví dụ, bạn có thể làm tổ isBanana bên trong main.

void main() {
  bool isBanana(String fruit) {
    return fruit == 'banana';
  }

  var fruit = 'apple';
  print(isBanana(fruit)); // false
}

Bạn cũng có thể thay đổi đối số thành một hàm, sau đó gọi lại đối số đó bằng đối số mới:

fruit = 'banana';
print(isBanana(fruit));  // true

Kết quả của việc gọi hàm phụ thuộc hoàn toàn vào các đối số bạn truyền vào.

Optional Parameters

Nếu một tham số cho một hàm là tùy chọn, bạn có thể bao quanh nó bằng dấu ngoặc vuông và đặt kiểu là vô hiệu:

String fullName(String first, String last, [String? title]) {
  if (title == null) {
    return '$first $last';
  } else {
    return '$title $first $last';
  }
}

Trong chức năng này, title là tùy chọn. Nó sẽ mặc định thành null nếu bạn không chỉ định nó.

Bây giờ, bạn có thể gọi hàm có hoặc không có tham số tùy chọn:

print(fullName('Joe', 'Howard'));
// Joe Howard

print(fullName('Albert', 'Einstein', 'Professor'));
// Professor Albert Einstein

Named Parameters and Default Values

Khi bạn có nhiều tham số, bạn có thể nhầm lẫn khi nhớ cái nào là cái nào. Dart giải quyết vấn đề này với các tham số được đặt tên , mà bạn nhận được bằng cách bao quanh danh sách tham số bằng dấu ngoặc nhọn { }.

Các tham số này là tùy chọn theo mặc định, nhưng bạn có thể cung cấp cho chúng các giá trị mặc định hoặc yêu cầu chúng bằng cách sử dụng từ khóa required:

bool withinTolerance({required int value, int min = 0, int max = 10}) {
  return min <= value && value <= max;
}

valuelà bắt buộc, trong khi minvà maxlà tùy chọn với các giá trị mặc định.

Với các tham số được đặt tên, bạn có thể chuyển vào các đối số theo một thứ tự khác bằng cách cung cấp các tên tham số bằng dấu hai chấm:

print(withinTolerance(value: 5)); // true

Chạy mã của bạn để xem các chức năng mới của bạn đang hoạt động.

Anonymous Functions

Dart hỗ trợ first-class functions , nghĩa là nó xử lý các hàm giống như bất kỳ kiểu dữ liệu nào khác. Bạn có thể gán chúng cho các biến, chuyển chúng dưới dạng đối số và trả lại chúng từ các hàm khác.

Để chuyển các hàm này xung quanh dưới dạng giá trị, hãy bỏ qua tên hàm và kiểu trả về. Vì không có tên nên loại hàm này được gọi là hàm ẩn danh .

Bạn có thể gán một hàm ẩn danh cho một biến có tên onPressed như sau:

final onPressed = () {
  print('button pressed');
};

onPressedcó giá trị kiểu Function. Các dấu ngoặc trống cho biết hàm không có tham số. Giống như các hàm thông thường, mã bên trong dấu ngoặc nhọn là phần thân của hàm.

Để thực thi mã bên trong thân hàm, hãy gọi tên biến như thể nó là tên của hàm:

onPressed(); // button pressed

Bạn có thể đơn giản hóa các hàm có nội dung chỉ chứa một dòng duy nhất bằng cách sử dụng cú pháp mũi tên . Để thực hiện việc này, hãy xóa dấu ngoặc nhọn và thêm một mũi tên =>.

Dưới đây là so sánh của hàm ẩn danh ở trên và phiên bản đã cấu trúc lại:

// original anonymous function
final onPressed = () {
  print('button pressed');
};

// refactored
final onPressed = () => print('button pressed');

Sử dụng Anonymous Functions

Bạn sẽ thường thấy các hàm ẩn danh trong Flutter, giống như các hàm ở trên, được chuyển xung quanh dưới dạng lệnh gọi lại cho các sự kiện giao diện người dùng. Điều này cho phép bạn chỉ định mã chạy khi người dùng làm điều gì đó, chẳng hạn như nhấn một nút.

Một nơi phổ biến khác mà bạn sẽ thấy các chức năng ẩn danh là với các collection. Bạn có thể cung cấp cho tập hợp một hàm ẩn danh sẽ thực hiện một số tác vụ trên mỗi phần tử của tập hợp. Ví dụ:

// 1
final drinks = ['water', 'juice', 'milk'];
// 2
final bigDrinks = drinks.map(
  // 3
  (drink) => drink.toUpperCase()
);
// 4
print(bigDrinks); // (WATER, JUICE, MILK)

Hãy xem xét từng bước:

  1. Xác định danh sách drinks có các chữ cái thường.
  2. .map nhận tất cả các giá trị danh sách và trả về một tập hợp mới với chúng.
  3. Một hàm ẩn danh được chuyển dưới dạng một tham số. Trong hàm ẩn danh đó, bạn có một drink đối số đại diện cho từng phần tử của danh sách.
  4. Phần thân của hàm ẩn danh chuyển đổi từng phần tử thành chữ hoa và trả về giá trị. Vì danh sách ban đầu là danh sách các chuỗi, nên drink cũng có kiểu String.

Sử dụng một hàm ẩn danh và kết hợp nó với .maplà một cách thuận tiện để chuyển đổi một bộ sưu tập này thành một bộ sưu tập khác. Lưu ý : Đừng nhầm giữa .mapmethod với Maptype.

Chạy mã để xem bộ sưu tập kết quả.

Xin chúc mừng, bạn đã hoàn thành phần hướng dẫn. Bây giờ bạn sẽ hiểu rõ hơn về mã Dart mà bạn thấy khi học cách xây dựng ứng dụng Flutter!

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

You may also like