Chuyển đến nội dung chính

Dart Basics


 

Phụ lục:

  1. Getting Started

  2. Why Dart?

  3. Core Concepts

  4. Variables, Comments và Data Types

  •  Comments

  •  Data Types

  •  Basic Dart Types

  •  The Dynamic Keyword

  •  Booleans

  1. Operators

  •  Arithmetic Operators

  •  Equality Operators

  •  Comparison Operators

  •  Logical Operators

  1. Strings

  •  Escaping Strings

  1. Immutability

  2. Nullability

  •  Null-Aware Operators

  1. Control Flow

  2. Conditionals

  •  If Statements

  •  Else Statements

  1. While Loops

  •  Testing the While Loop

  •  Trying Out the Do-While Loop

  1. Continue and Break

  2. For Loops

  3. Collections

  4. Lists

  •  Working With List Elements

  1. Maps

  2. Functions

  •  Defining Functions

  •  Working With Functions

  •  Nesting Functions

  •  Optional Parameters

  •  Named Parameters and Default Values

  •  Anonymous Functions

  •  Using Anonymous Functions

  1. Where to Go From Here?


Flutter là một bộ công cụ giao diện người dùng thú vị của Google cho phép bạn viết ứng dụng cho các nền tảng khác nhau bao gồm IOS, Android, web và hơn thế nữa, tất cả đều sử dụng một codebase. Flutter sử dụng ngôn ngữ Dart.


Nếu bạn chưa quen với Dart, hướng dẫn này sẽ giới thiệu cho bạn các khái niệm cơ bản của nó và cho bạn thấy nó tương tự như thế nào với các ngôn ngữ lập trình khác mà bạn có thể đã biết.


  1. Getting Started


Bạn có thể dán mã từ main.dart vào DartPad hoặc sử dụng Dart SDK để chạy tệp.


Để bắt đầu nhanh chóng, cách tốt nhất của bạn là sử dụng công cụ mã nguồn mở DartPad, cho phép bạn viết và kiểm tra mã Dart thông qua trình duyệt web:



DartPad được thiết lập giống như một IDE thông thường. Nó bao gồm các thành phần sau:


  • Editor pane: Nằm ở bên trái. Mã của bạn sẽ xuất hiện ở đây.

  • Nút RUN: Chạy mã trong trình chỉnh sửa.

  • Console: Nằm ở phía trên bên phải, bảng này hiển thị đầu ra.

  • Documentation panel: Nằm ở phía dưới bên phải, bảng này hiển thị thông tin 

về mã.

  • Samples: Trình đơn thả xuống này hiển thị một số mã mẫu.

  • Nút Null Safety: Sử dụng nút này để chọn tham gia vào tính năng an toàn không 

có âm thanh mới của Dart.

  • Thông tin phiên bản: Ở phía dưới cùng bên phải, DartPad hiển thị phiên bản Flutter và Dart mà nó hiện đang sử dụng.


Nếu muốn, bạn có thể cài đặt Dart SDK cục bộ trên máy của mình. Một cách để làm như vậy là cài đặt Flutter SDK. Cài đặt Flutter cũng sẽ cài đặt Dart SDK.


Để cài đặt Dart SDK trực tiếp, hãy truy cập https://dart.dev/get-dart.


2. Why Dart?


Dart có nhiều điểm tương đồng với các ngôn ngữ khác như Java, C#, Swift và Kotlin.

Một số tính năng của nó bao gồm:


  • Đã nhập tĩnh

  • Nhập suy luận

  • Biểu thức chuỗi

  • Đa mô hình bao gồm lập trình hướng đối tượng và chức năng

  • Không an toàn


Dart được tối ưu hóa để phát triển các ứng dụng nhanh trên nhiều nền tảng.


3. Core Concepts


Các chương trình dart bắt đầu với một cuộc gọi đến chính. Cú pháp của Dart cho main

trông tương tự như cú pháp của các ngôn ngữ khác như C, Swift hoặc Kotlin.


Xóa tất cả mã trong DartPad mặc định và thêm main vào trình chỉnh sửa:


void main() {
}

Bạn sẽ thấy có một loại trả lại trước chính. Trong trường hợp này, nó vô hiệu, nghĩa là main sẽ không trả về bất cứ thứ gì.


Dấu ngoặc đơn sau main cho biết đây là một định nghĩa hàm. Dấu ngoặc nhọn chứa phần thân của hàm.


Bên trong main, bạn thêm mã Dart cho chương trình của mình.


Tiếp theo, bạn sẽ tìm hiểu thêm về các khái niệm cốt lõi sau:


  • Variables, Comments and Data Types

  • Basic Dart Types

  • Operators

  • Strings

  • Immutability

  • Nullability

  • Condition and Break

  • For Loops


Đã đến lúc đi sâu vào!


4. Variables, Comments và Data Types


Điều đầu tiên bạn sẽ thêm vào main là một câu lệnh gán biến. Các biến giữ dữ liệu mà

chương trình của bạn sẽ hoạt động.


Bạn có thể coi một biến là một hộp trong bộ nhớ máy tính của bạn chứa một giá trị. Mỗi hộp có một tên, đó là tên của biến. Để biểu thị một biến bằng Dart, hãy sử dụng từ khóa var.


Thêm một biến mới vào main:


var myAge = 35;

Mỗi câu lệnh Dart kết thúc bằng dấu chấm phẩy, giống như các câu lệnh trong C và Java. Trong đoạn mã trên, bạn đã tạo một biến, myAge và đặt nó bằng 35.


Bạn có thể sử dụng bản in tích hợp trong Dart để in biến vào bảng điều khiển. Thêm lệnh gọi đó sau biến:


print(myAge); // 35

Nhấp vào RUN trong DartPad để chạy mã. Bạn sẽ thấy giá trị của biến, 35, được in trong bảng điều khiển.


  • Comments


Comments trong Dart giống như trong C và các ngôn ngữ khác: Văn bản sau // là một nhận xét một dòng, trong khi văn bản trong / * ... * / là một khối nhận xét nhiều dòng.


Đây là một ví dụ:


// This is a single-line comment.

print(myAge); // This is also a single-line comment.

/*
This is a multi-line comment block. This is useful for long
comments that span several lines.
*/


  • Data Types


Dart được nhập tĩnh, có nghĩa là mỗi biến trong Dart có một kiểu mà bạn phải biết khi biên dịch mã. Loại biến không thể thay đổi khi bạn chạy chương trình. C, Java, Swift và Kotlin cũng được gõ tĩnh.


Điều này trái ngược với các ngôn ngữ như Python và JavaScript, được gõ động. Điều đó có nghĩa là các biến có thể chứa các loại dữ liệu khác nhau khi bạn chạy chương trình. Bạn không cần biết loại khi bạn biên dịch mã.


Nhấp vào myAge trong cửa sổ trình chỉnh sửa và xem trong Documentation panel. Bạn sẽ thấy Dart suy ra rằng myAge là một int vì nó được khởi tạo với giá trị số nguyên 35.


Nếu bạn không chỉ định rõ ràng một kiểu dữ liệu, Dart sẽ sử dụng suy luận kiểu để cố gắng xác định nó, giống như Swift và Kotlin.




Dart cũng sử dụng kiểu suy luận cho các kiểu khác với int. Nhập một biến, pi, bằng 3,14:

var pi = 3.14;

print(pi); // 3.14

Dart cho rằng số pi là một double bởi vì bạn đã sử dụng một giá trị dấu phẩy động để khởi tạo nó. Bạn có thể xác minh điều đó trong bảng thông tin Dart bằng cách nhấp vào số pi.


Ngoài ra, thay vì sử dụng kiểu suy luận, bạn có thể khai báo kiểu.


  • Basic Dart Types


Dart sử dụng các loại cơ bản sau:


  • int: Số nguyên

  • double: Số dấu phẩy động

  • bool: Booleans

  • String: Chuỗi ký tự


Dưới đây là ví dụ về từng loại Dart:



int và double đều bắt nguồn từ một kiểu có tên là num. num sử dụng từ khóa động để bắt chước cách nhập động trong Dart được nhập tĩnh.


Thực hiện việc này bằng cách thay thế var bằng kiểu bạn muốn sử dụng:


int yourAge = 27;

print(yourAge); // 27


  • The Dynamic Keyword


Nếu bạn sử dụng từ khóa dynamic thay vì var, bạn sẽ có được biến được nhập động một cách hiệu quả:


dynamic numberOfKittens;


Tại đây, bạn có thể đặt numberOfKittens thành String bằng cách sử dụng dấu ngoặc kép. Bạn sẽ tìm hiểu thêm về loại String sau trong hướng dẫn.

numberOfKittens = 'There are no kittens!';

print(numberOfKittens); // There are no kittens!

numberOfKittens có một kiểu, vì Dart có kiểu gõ tĩnh. Nhưng kiểu đó là dynamic, có nghĩa là bạn có thể gán các giá trị khác với các kiểu khác cho nó. Vì vậy, bạn có thể gán một giá trị int bên dưới câu lệnh in của mình.

numberOfKittens = 0;

print(numberOfKittens); // 0

Hoặc, nếu bạn có một con mèo con trong hộp của Schrödinger, bạn có thể gán một giá trị kép:



numberOfKittens = 0.5;

print(numberOfKittens); // 0.5


Nhấp vào Run để xem ba giá trị khác nhau cho numberOfKittens được in trong bảng điều khiển. Trong mỗi trường hợp, kiểu numberOfKittens vẫn động, mặc dù bản thân biến giữ các giá trị thuộc các kiểu khác nhau.




  • Booleans


Kiểu bool chứa các giá trị true hoặc false.


bool areThereKittens = false;

print(areThereKittens); // false

Tuy nhiên, nếu bạn nhìn vào bên trong hộp của Schrödinger, bạn có thể chuyển sang có một con mèo con thực sự sống:

numberOfKittens = 1;

areThereKittens = true;

print(areThereKittens); // true

Chạy lại mã để xem các giá trị Boolean của bạn trong bảng điều khiển. Đó là một điều tốt khi bạn nhìn vào hộp!



5. Operators

Dart có tất cả các toán tử thông thường mà bạn quen thuộc từ các ngôn ngữ khác như C, Swift và Kotlin.


Một số ví dụ về các toán tử của Dart bao gồm:


  • Môn số học

  • bình đẳng

  • tăng và giảm

  • sự so sánh

  • hợp lý


Lưu ý: Dart cũng cho phép nạp chồng toán tử, như trong C ++ và Kotlin, nhưng điều đó nằm ngoài phạm vi của hướng dẫn này. Để tìm hiểu thêm về chủ đề, hãy truy cập trang overator overloading Wikipedia.


Tiếp theo, bạn sẽ xem xét từng toán tử này.


  • Arithmetic Operators


Arithmetic operators hoạt động như bạn mong đợi. Hãy thử chúng bằng cách thêm một loạt các thao tác vào DartPad của bạn:


print(40 + 2); // 42

print(44 - 2); // 42

print(21 * 2); // 42

print(84 / 2); // 42.0


Đối với phép chia, ngay cả với số nguyên, Dart suy luận biến kết quả là một double. Đó là lý do tại sao bạn nhận được 42.0 thay vì 42 cho báo cáo print cuối cùng.


Lưu ý: DartPad hiển thị kết quả “84/2” là 42 trong bảng điều khiển vì nó định dạng đầu ra cho bảng điều khiển để chỉ hiển thị các chữ số có nghĩa. Nếu bạn in câu lệnh tương tự trong chương trình Dart từ SDK Dart, kết quả là bạn sẽ nhận được 42.0.

  • Equality Operators

Dart sử dụng các toán tử bình đẳng double-equals (==) và not-equals (! =):


print(42 == 43); // false

print(42 != 43); // true



  • Comparison Operators


Dart sử dụng các toán tử so sánh điển hình:


  • Nhỏ hơn (<)

  •  Lớn hơn (>)

  • Bằng (=>)


Dưới đây là một số ví dụ:


print(42 < 43); // true print(42 >= 43); // false


Ngoài ra, nó cũng sử dụng các toán tử số học / phép gán ghép thông thường:

var value = 42.0;

value += 1; print(value); // 43.0

value -= 1; print(value); // 42.0

value *= 2; print(value); // 84.0

value /= 2; print(value); // 42.0

Toán tử số học / phép gán ghép thực hiện hai nhiệm vụ. + = thêm giá trị ở bên phải vào biến ở bên trái và sau đó gán kết quả cho biến.


Dạng rút gọn của + = 1 là ++:


value++;

print(value); // 43.0

Và Dart có toán tử modulo thông thường (%) để trả về phần còn lại sau khi một số đã được chia cho một số khác:

print(392 % 50); // 42

392 ÷ 50 = 7,84, nhưng 42 đó trong ngăn kết quả đến từ đâu? Nó dễ thấy hơn với sự phân chia dài.


  • Logical Operators


Dart sử dụng các toán tử logic giống như các ngôn ngữ khác, bao gồm && cho AND và || cho OR.


print((41 < 42) && (42 < 43)); // true

print((41 < 42) || (42 > 43)); // true


Toán tử phủ định là dấu chấm than, biến false thành true và true thành false.


print(!(41 < 42)); // false

Xem Dart documentation để biết danh sách đầy đủ supported operators.



 6. Strings


The Dart string là String. Strings được thể hiện trong Dart bằng cách sử dụng văn bản được bao quanh bởi dấu ngoặc kép đơn hoặc kép.


Bạn có thể sử dụng var và type inference hoặc String để tạo biến chuỗi, giống như các kiểu khác mà bạn đã thấy:


var firstName = 'Albert';

String lastName = "Einstein";

Tương tự như các ngôn ngữ như Kotlin và Swift, bạn có thể nhúng giá trị của một biểu thức bên trong một chuỗi bằng cách sử dụng ký hiệu dấu đô la: ${expression}.


Nếu biểu thức là số nhận dạng, bạn có thể bỏ qua dấu {}. Thêm những điều sau:


var physicist = "$firstName $lastName likes the number ${84 / 2}";

print(physicist); // Albert Einstein


  • Escaping Strings


Các trình tự thoát được sử dụng trong Dart tương tự như các trình tự được sử dụng trong các ngôn ngữ giống C khác. Ví dụ: bạn sử dụng \n cho một dòng mới.


Nếu có các ký tự đặc biệt trong chuỗi, hãy sử dụng \ để thoát khỏi chúng:


var quote = 'If you can\'t explain it simply\nyou don\'t understand it well enough.';

print(quote);

// If you can't explain it simply

// you don't understand it well enough.

Ví dụ này sử dụng các dấu ngoặc kép, vì vậy nó cần một chuỗi thoát, \', để nhúng các dấu nháy đơn for can’t and don’t vào chuỗi. Bạn sẽ không cần phải thoát khỏi dấu nháy đơn nếu thay vào đó bạn đã sử dụng dấu ngoặc kép.


Nếu bạn cần hiển thị trình tự thoát trong chuỗi, bạn có thể sử dụng chuỗi thô, có tiền tố là r.


var rawString = r"If you can't explain it simply\nyou don't understand it well enough.";

print(rawString);

// If you can't explain it simply\nyou don't understand it well enough.

Ở đây, Dart coi `\n` là văn bản bình thường vì chuỗi bắt đầu bằng r.


Nhấp vào RUN trong DartPad để xem tất cả các chuỗi của bạn trong bảng điều khiển.



7. Immutability


Dart sử dụng các từ khóa const và final cho các giá trị không thay đổi.


Sử dụng const cho các giá trị đã biết tại thời gian biên dịch. Sử dụng giá trị final cho các giá trị không cần biết tại thời điểm biên dịch nhưng không thể gán lại sau khi được khởi tạo.


Lưu ý: các hành động final như val trong Kotlin hoặc let trong Swift.


Bạn có thể sử dụng const và final thay cho var và để kiểu suy luận xác định kiểu:


const speedOfLight = 299792458;

print(speedOfLight); // 299792458

Ở đây, Dart suy luận rằng speedOfLight là một int, như bạn có thể thấy trong bảng thông tin của DartPad.


final chỉ ra rằng một biến là không thể thay đổi, nghĩa là bạn không thể chỉ định lại các giá trị final. Bạn có thể xác định rõ ràng kiểu với final hoặc const:


final planet = 'Jupiter';

// planet = 'Mars';

// error: planet can only be set once

final String moon = 'Europa';

print('$planet has a moon, $moon');

// Jupiter has a moon, Europa

8. Nullability


Trước đây, nếu bạn không khởi tạo một biến, Dart đã cho nó giá trị null, có nghĩa là không có gì được lưu trữ trong biến. Tuy nhiên, kể từ Dart 2.12, Dart kết hợp với các ngôn ngữ khác, như Swift và Kotlin, để trở thành không thể null theo mặc định.


Ngoài ra, Dart đảm bảo rằng kiểu không thể null sẽ không bao giờ chứa giá trị null. Điều này được gọi là an toàn không có âm thanh.


Thông thường, nếu bạn muốn khai báo một biến, bạn phải khởi tạo nó:


String middleName = 'May';

print(middleName); // May

Tuy nhiên, không phải tất cả mọi người đều có tên đệm, do đó, việc đặt middleName là một giá trị vô hiệu. Để nói với Dart rằng bạn muốn cho phép giá trị null, hãy thêm? sau khi loại.

String? middleName = null;

print(middleName); // null

Giá trị mặc định cho kiểu nullable là null, vì vậy bạn có thể đơn giản hóa biểu thức thành như sau:

String? middleName;

print(middleName); // null

Chạy và in null vào bảng điều khiển.



  • Null-Aware Operators


Dart có một số toán tử nhận biết null mà bạn có thể sử dụng khi làm việc với các giá trị null.


Toán tử dấu chấm hỏi kép, ??, giống như toán tử Elvis trong Kotlin: Nó trả về toán hạng bên trái nếu đối tượng không rỗng. Nếu không, nó trả về giá trị bên phải:


var name = middleName ?? 'none';

print(name); // none

Vì middleName là null, Dart chỉ định giá trị bên phải của 'none'.


Các ?. toán tử bảo vệ bạn khỏi việc truy cập các thuộc tính của các đối tượng null. Nó trả về null nếu bản thân đối tượng là null. Nếu không, nó trả về giá trị của thuộc tính ở phía bên phải:


print(middleName?.length); // null

Trong những ngày trước khi an toàn rỗng, nếu bạn quên dấu chấm hỏi và viết middleName.length, ứng dụng của bạn sẽ gặp sự cố trong thời gian chạy nếu middleName không có giá trị. Đó không còn là vấn đề nữa, vì Dart giờ đây sẽ cho bạn biết ngay lập tức khi nào bạn cần xử lý các giá trị null.

9. Control Flow

Luồng điều khiển cho phép bạn ra lệnh khi nào thực thi, bỏ qua hoặc lặp lại một số dòng mã nhất định. Bạn sử dụng các điều kiện và vòng lặp để xử lý luồng điều khiển trong Dart.


Trong phần này, bạn sẽ tìm hiểu thêm về:


  • Điều kiện

  • Vòng lặp trong khi

  • Tiếp tục và Phá vỡ

  • Đối với các vòng lặp


Dưới đây là những điều bạn cần biết về các phần tử luồng điều khiển trong Dart.


10. Conditionals


Hình thức cơ bản nhất của luồng điều khiển là quyết định thực thi hay bỏ qua các phần nhất định của mã của bạn, tùy thuộc vào các điều kiện xảy ra khi chương trình của bạn chạy.


Cấu trúc ngôn ngữ để xử lý các điều kiện là câu lệnh if/else. if/else trong Dart trông gần giống với việc sử dụng nó trong các ngôn ngữ giống C khác.

  • If Statements

Giả sử bạn có một biến, động vật, hiện là một con cáo. Nó trông như thế này:


var animal = 'fox';

Bạn có thể sử dụng câu lệnh if để kiểm tra xem động vật là mèo hay chó, sau đó chạy một số mã tương ứng.

f (animal == 'cat' || animal == 'dog') {
print('Animal is a house pet.');
}

Ở đây, bạn đã sử dụng các toán tử bình đẳng và OR để tạo bool bên trong điều kiện cho câu lệnh if.

  • Else Statements


Với mệnh đề else, bạn có thể chạy mã thay thế nếu điều kiện sai:


else {
print('Animal is NOT a house pet.');
}
// Animal is NOT a house pet.

Bạn cũng có thể kết hợp nhiều câu lệnh if/else thành một cấu trúc if/else if /else:

if (animal == 'cat' || animal == 'dog') {
print('Animal is a house pet.');
} else if (animal == 'rhino') {
print('That\'s a big animal.');
} else {
print('Animal is NOT a house pet.');
}
// Animal is NOT a house pet.

Bạn có thể có nhiều nhánh if khác giữa if và else nếu bạn cần.


11. While Loops ( vòng lặp )


Vòng lặp cho phép bạn lặp lại mã một số lần nhất định hoặc dựa trên các điều kiện nhất định. Bạn xử lý sự lặp lại dựa trên điều kiện bằng cách sử dụng vòng lặp while.


Có hai dạng vòng lặp while trong Dart: while và do-while. Sự khác biệt là trong khi, điều kiện lặp lại xảy ra trước khối mã. Trong do-while, điều kiện xảy ra sau. Điều đó có nghĩa là các vòng lặp do-while đảm bảo khối mã chạy ít nhất một lần.


  • Testing the While Loop


Để thử điều này, hãy tạo một biến tôi đã khởi tạo thành 1:


var i = 1;

Tiếp theo, sử dụng vòng lặp while để in i trong khi tăng dần. Đặt điều kiện là i nhỏ hơn 10:

while (i < 10) {
print(i);
i++;
}
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9

Chạy mã và bạn sẽ thấy rằng vòng lặp while in các số từ 1 đến 9.


  • Trying Out the Do-While Loop


Đặt lại i trong DartPad, sau đó thêm vòng lặp do-while:


i = 1;
do {
print(i);
i++;
} while (i < 10);
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9

Kết quả vẫn giống như trước đây. Tuy nhiên, lần này, phần thân của vòng lặp đã chạy một lần trước khi kiểm tra điều kiện thoát vòng lặp.


12. Continue and Break


Dart sử dụng các từ khóa continue và break trong các vòng lặp và các từ khóa khác. Đây là những gì họ làm:


  • continue: Bỏ qua mã còn lại bên trong một vòng lặp và ngay lập tức chuyển sang 

lần lặp tiếp theo.

  • break: Dừng vòng lặp và tiếp tục thực hiện sau phần thân của vòng lặp.


Hãy cẩn thận khi sử dụng continue trong mã của bạn. Ví dụ: nếu bạn sử dụng vòng lặp do-while ở trên và bạn muốn tiếp tục khi i bằng 5, điều đó có thể dẫn đến một vòng lặp vô hạn tùy thuộc vào vị trí bạn đặt câu lệnh continue:


i = 1;
do {
print(i);
if (i == 5) {
continue;
}
++i;
} while (i < 10);
// 1
// 2
// 3
// 4
// 5
// 5
// 5
// 5
// 5
// 5
// 5
// 5
// 5
// 5
// ...

Vòng lặp vô hạn xảy ra bởi vì, khi i là 5, bạn không bao giờ tăng nó nữa, vì vậy điều kiện luôn đúng.


Nếu bạn chạy điều này trong DartPad, vòng lặp vô hạn sẽ khiến trình duyệt bị treo. Thay vào đó, hãy sử dụng break, để vòng lặp kết thúc sau khi i đạt đến 5:


i = 1;
do {
print(i);
if (i == 5) {
break;
}
++i;
} while (i < 10);
// 1
// 2
// 3
// 4
// 5

Chạy mã. Bây giờ, vòng lặp kết thúc sau năm lần lặp.


13. For Loops


Trong Dart, bạn sử dụng vòng lặp for để lặp lại một số lần được xác định trước. vòng lặp for bao gồm khởi tạo, điều kiện vòng lặp và một hành động. Một lần nữa, chúng tương tự như vòng lặp for trong các ngôn ngữ khác.


Dart cũng cung cấp một vòng lặp for-in, lặp lại trên một tập hợp các đối tượng. Bạn sẽ tìm hiểu thêm về những điều này sau.


Để xem cách hoạt động của vòng lặp for, hãy tạo một biến cho tổng:


var sum = 0;

Tiếp theo, sử dụng vòng lặp for để khởi tạo bộ đếm vòng lặp từ i đến 1. Sau đó, bạn sẽ kiểm tra xem i nhỏ hơn hoặc bằng 10 và tăng i sau mỗi vòng lặp.


Bên trong vòng lặp, sử dụng phép gán ghép để thêm i vào tổng đang chạy:


for (var i = 1; i <= 10; i++) {
sum += i;
}
print("The sum is $sum"); // The sum is 55

Chạy mã của bạn trong DartPad để xem tổng.


14. Collections


Bộ sưu tập rất hữu ích cho việc 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.


15. Lists


Lists trong Dart tương tự như mảng 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 vào numbers trong DartPad và bạn sẽ thấy rằng Dart nhận dạng loại là List các int.


  • Working With List Elements


Để 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ố 0, nên 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 and 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ề vòng lặp for. Vòng lặp for-in của Dart hoạt động đặc biệt tốt với các danh sách. Hãy dùng thử:

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 lại mọi phần tử của dessert và gán nó mỗi lần cho một biến có tên dessert.


Cảm thấy đói bụng? Chà, bạn không thể ăn bất kỳ món tráng miệng nào cho đến khi ăn xong rau. :)


16. Maps


Khi bạn muốn một danh sách các giá trị được ghép nối, Bản đồ là một lựa chọn tốt. Dart Maps

tương tự như từ điển trong Swift và bản đồ trong Kotlin.





Dưới đây là một ví dụ về bản đồ 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

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


Nhấp vào donutCalories trong DartPad và bạn sẽ thấy rằng kiểu được suy ra là int? thay vì 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ề 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 new dessert của bạn ở cuối.


17. 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:


-Loại trả lại

-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


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ề 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ề thành void. main làm điều này, chẳng hạn.


  • Working With Functions


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 lệnh gọi đó để print:


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

  • Nesting Functions


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ồng 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à làm cho kiểu này 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 là 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 làm cho chúng bắt buộc 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;
}

value là bắt buộc, trong khi min và max là 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(min: 1, max: 5, value: 11)); // false

Bạn có thể loại bỏ các tham số với giá trị mặc định khi gọi hà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ợ các hàm hạng nhất, 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. (anonymous function)


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');
};

onPressed có 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. Để làm điều này, loại bỏ dấu ngoặc nhọn và thêm một mũi tên béo =>.


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


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

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

Điều đó đẹp hơn nhiều để đọc.


  • Using 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 bộ sưu tập. Bạn có thể cung cấp cho tập hợp một chức năng ẩ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:


-Xác định danh sách drinks có các chữ cái viết thường.

-.map lấy 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.

-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 đối số drinks đại diện cho từng phần tử của danh sách.

-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 drinks cũng có loại String.


Sử dụng một hàm ẩn danh và kết hợp nó với .map là 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 lẫn phương thức .map với loại Map.


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



Xin chúc mừng, bạn đã hoàn thành 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!


18. Where to Go From Here?


Nếu bạn đã sẵn sàng tìm hiểu về Flutter, hãy xem hướng dẫn Getting Started With Flutter.


Để có cái nhìn toàn diện hơn về Flutter, hãy đọc cuốn sách của chúng tôi, Flutter Apprentice.


Bạn có thể vượt ra ngoài những điều cơ bản và tìm hiểu thêm về Lập trình hướng đối tượng và lập trình không đồng bộ với cuốn sách của chúng tôi, Dart Apprentice.


Ngoài ra, hãy xem Dart documentation.


Chúng tôi hy vọng bạn thích phần giới thiệu cơ bản về Dart này. Nếu bạn có bất kỳ câu hỏi hoặc ý kiến nào, vui lòng tham gia thảo luận của diễn đàn bên dưới.


Nhận xét

Bài đăng phổ biến từ blog này

Jetpack Compose VS SwiftUI !VS Flutter

  Việc phát triển Android đã trở nên dễ dàng hơn khi các bản cập nhật liên tục đến. Sau bản cập nhật 2020.3.1, rất nhiều thứ đã thay đổi. Nhưng thay đổi chính mà tôi nghĩ hầu hết các nhà phát triển phải chờ đợi là Jetpack Compose cho ứng dụng sản xuất. Và Kotlin là lựa chọn duy nhất cho jetpack Compose, cũng là ngôn ngữ được ưu tiên. Để biết thêm chi tiết hoặc các thay đổi trên Jetpack Compose, bạn có thể truy cập vào https://developer.android.com/jetpack/compose Tương tự, IOS Development cũng cung cấp một tùy chọn để phát triển khai báo, SwiftUI. Trong IDE, không có thay đổi nào do điều này. Nhưng khái niệm gần giống với Jetpack Compose. Thay vì bảng phân cảnh, chúng tôi tạo giao diện người dùng bằng Swift. Để biết thêm chi tiết hoặc các thay đổi trên SwiftUI, hãy truy cập https://developer.apple.com/xcode/swiftui/ Hãy xem cách cả hai hoạt động bằng cách sử dụng một dự án demo. Tôi đã lấy một số ví dụ về số lần chạm tương tự của Flutter. 1. Android Jetpack Compose Chúng tôi có thể tạo

Thiết kế giao diện với DotNetBar (Phần 1)

Đây là phiên bản DotNetBar hỗ trợ C# và Visual Basic https://www.dropbox.com/s/wx80jpvgnlrmtux/DotNetBar.rar  , phiên bản này hỗ trợ giao diện Metro cực kỳ “dễ thương” Các bạn load về và cài đặt, khi cài đặt xong sẽ có source code mẫu của tất cả các control. Để sử dụng được các control của DotNetBar các bạn nhớ add item vào controls box. Thiết kế giao diện với DotNetBar, giao diện sẽ rất đẹp. Link các video hướng dẫn chi tiết cách sử dụng và coding: http://www.devcomponents.com/dotnetbar/movies.aspx Hiện tại DotNetBar có rất nhiều công cụ cực mạnh, trong đó có 3 công cụ dưới đây: DotNetBar for Windows Forms Requires with Visual Studio 2003, 2005, 2008, 2010 or 2012.   DotNetBar for WPF Requires with Visual Studio 2010 or 2012 and Windows Presentation Foundation.   DotNetBar for Silverlight Requires with Visual Studio 2010 or 2012 and Silverlight. Dưới đây là một số hình ảnh về các control trong DotnetBar.   Metro User Interface  controls with Metro Tiles, toolbars, slide panels, forms,

Một số bài tập Winform C#

Một số bài tập: 1. Mô phỏng game đoán số. Luật chơi:         o Đúng số và đúng vị trí   +         o Đúng số mà sai vị trí      ?         o Sai số và sai vị trí          -         . . .         - Kết quả được tạo ngẫu nhiên từ các số có 4 chữ số.         - Các chữ số có giá trị từ 0-6.         - Người chơi có 6 lần đoán. Chương trình tham khảo: 2. In số điện tử Yêu cầu: người dùng nhập vào 1 số ( hoặc 1 chuỗi số) yêu cầu in ra số đó dưới dạng số điện tử. Chương trình tham khảo: 3. Mô phỏng game CARO  (update) 4. Mô phỏng game DÒ MÌN (update)