Học Dart thông qua xem ví dụ

Phương pháp này sẽ giới thiệu ngắn gọn về ngôn ngữ cho những ai thích học qua ví dụ. Bạn cũng có thể học ngôn ngữ và xem các thư viện, hoặc Dart cheatsheet codelab tại:

Học ngôn ngữ

Xem thư viện

Hello World

Mọi ứng dụng đều cần có hàm main(). Để hiển thị văn bản trên console bạn có thẻ sử dụng hàm print():

void main() {
    print('Hello World');
}

Kiểu dữ liệu (Variables)

Trong dart hầu hết các biến không cần kiểu dữ liệu rõ ràng, nhờ vào suy luận kiểu (type inference):

var name = 'Voyager I';
var year = 1977;
var antennaDiameter = 3.7;
var flybyObjects = ['Jupiter', 'Saturn', 'Uranus', 'Neptune'];
var image = {
  'tags': ['saturn'],
  'url': '//path/to/saturn.jpg'
};

Đọc thêm các kiểu dữ liệu trong Dart: bao gồm các kiểu giá trị mặc định default, final, const và static.

Các câu lệnh

Dart hỗ trợ các kiểu câu lệnh như:

if (year >= 2001) {
  print('21st century');
} else if (year >= 1901) {
  print('20th century');
}

for (var object in flybyObjects) {
  print(object);
}

for (int month = 1; month <= 12; month++) {
  print(month);
}

while (year < 2016) {
  year += 1;
}

Đọc thêm về các câu lệnh trong Dart gồm break và continue, switch và case, và assert.

Các hàm (Functions)

Chúng ta định nghĩa cụ thể kiểu cho từng hàm và trả về kết quả:

int fibonacci(int n) {
  if (n == 0 || n == 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

var result = fibonacci(20);

Cú pháp nhanh arrow functions => (arrow) có ích cho các hàm chứa một câu lệnh. Cú pháp này đặc biệt hữu ích khi truyền các hàm ẩn danh dưới dạng đối số:

flybyObjects.where((name) => name.contains('turn')).forEach(print);

Bên cạnh việc hiển thị một hàm ẩn danh (đối số tới where ()), đoạn code này cho thấy rằng bạn có thể sử dụng một hàm làm đối số: hàm print () là một đối số cho hàm forEach ().

Đọc thêm về các hàm trong Dart, bao gồm các tham số tùy chọn, giá trị tham số mặc định.

Comments

Trong Dart chúng ta comments bắt đầu với //

// This is a normal, one-line comment.

/// This is a documentation comment, used to document libraries,
/// classes, and their members. Tools like IDEs and dartdoc treat
/// doc comments specially.

/* Comments like these are also supported. */

Đọc thêm về các kiểu Comments ​​trong Dart, bao gồm tài liệu công cụ thử hiện.

Imports

Để truy xuất APIs được định nghĩa trong các thư viện khác chúng ta sử dụng import.

// Importing core libraries
import 'dart:math';

// Importing libraries from external packages
import 'package:test/test.dart';

// Importing files
import 'path/to/my_other_file.dart';

Đọc thêm về thư viện và tính khả dụng trong Dart, including library prefixes, show and hide, and lazy loading through the deferred keyword.

Classes

Đây là một ví dụ về một lớp có ba thuộc tính, hai hàm tạo và một phương thức. Một trong những thuộc tính không thể thiết lập (set) trực tiếp do đó nó được định nghĩa bằng cách sử dụng phương thức getter (thay vì một biến).

class Spacecraft {
  String name;
  DateTime launchDate;

  // Constructor, with syntactic sugar for assignment to members.
  Spacecraft(this.name, this.launchDate) {
    // Initialization code goes here.
  }

  // Named constructor that forwards to the default one.
  Spacecraft.unlaunched(String name) : this(name, null);

  int get launchYear =>
      launchDate?.year; // read-only non-final property

  // Method.
  void describe() {
    print('Spacecraft: $name');
    if (launchDate != null) {
      int years =
          DateTime.now().difference(launchDate).inDays ~/
              365;
      print('Launched: $launchYear ($years years ago)');
    } else {
      print('Unlaunched');
    }
  }
}

Chúng ta có thể sử dụng lớp Spacecraft như sau:

var voyager = Spacecraft('Voyager I', DateTime(1977, 9, 5));
voyager.describe();

var voyager3 = Spacecraft.unlaunched('Voyager III');
voyager3.describe();

Đọc thêm về các lớp trong Dart, bao gồm danh sách khởi tạo, từ khóa newconst, redirecting constructors, factory constructors, getters, setters, và nhiều hơn nữa.

Kế thừa

Dart có đơn kế thừa:

class Orbiter extends Spacecraft {
  num altitude;
  Orbiter(String name, DateTime launchDate, this.altitude)
      : super(name, launchDate);
}

Đọc thêm về việc mở rộng các lớp, @override và hơn thế nữa.

Mixins

Mixins là một cách sử dụng lại code trong nhiều lớp phân cấp. Lớp sau đây có thể hoạt động như một mixin:

class Piloted {
  int astronauts = 1;
  void describeCrew() {
    print('Number of astronauts: $astronauts');
  }
}

Để thêm mixin vào một lớp, chỉ cần kế thừa lớp với mixin với từ khóa with.

class PilotedCraft extends Spacecraft with Piloted {
  // ···
}

PilotedCraft now has the astronauts field as well as the describeCrew() method.

Đọc thêm về mixins.

Interfaces và abstract classes

Dart không có từ khóa interface, thay vào đó mọi classes ngầm định nghĩa một interface. Vì vậy bạn có thể implement bất kì class nào:

class MockSpaceship implements Spacecraft {
  // ···
}

Đọc thêm về implicit interfaces. Bạn có thể tạo một lớp trừu tượng để extended (hoặc implemented) bởi một lớp cụ thể. Các lớp trừu tượng có thể chứa các phương thức trừu tượng (với các bodies rỗng).

abstract class Describable {
  void describe();

  void describeWithEmphasis() {
    print('=========');
    describe();
    print('=========');
  }
}

Bất kì lớp nào kết thừa Describable đều có phương thức describeWithEmphasis(), which calls the extender’s implementation of describe()

Đọc thêm về lớp các trừu tượng và phương thức

Async

Để tránh callback hell và code của bạn dễ đọc hơn chúng ta sử dụng asyncawait

const oneSecond = Duration(seconds: 1);
// ···
Future<void> printWithDelay(String message) async {
  await Future.delayed(oneSecond);
  print(message);
}

Phương thức trên tương đương với:

Future<void> printWithDelay(String message) {
  return Future.delayed(oneSecond).then((_) {
    print(message);
  });
}

Như ví dụ phía trên, asyncawait giúp code bất đồng bộ trở lên dễ đọc hơn

Future<void> createDescriptions(Iterable<String> objects) async {
  for (var object in objects) {
    try {
      var file = File('$object.txt');
      if (await file.exists()) {
        var modified = await file.lastModified();
        print(
            'File for $object already exists. It was modified on $modified.');
        continue;
      }
      await file.create();
      await file.writeAsString('Start describing $object in this file.');
    } on IOException catch (e) {
      print('Cannot create description for $object: $e');
    }
  }
}

Bạn có thể sử dụng async* cung cấp cho bạn một cách hay, dễ đọc để xây dựng các luồng.

Stream<String> report(Spacecraft craft, Iterable<String> objects) async* {
  for (var object in objects) {
    await Future.delayed(oneSecond);
    yield '${craft.name} flies by $object';
  }
}

Đọc thêm về hỗ trợ bất đồng bộ, bao gồm async functions, Future, Stream và vòng lặp bất đồng bộ (await for).

Exceptions

Đê bắt lỗi(exceptions) chúng ta sử dụng throw:

if (astronauts == 0) {
  throw StateError('No astronauts.');
}

Để băt(catch) exception, sử dụng câu lệnh try on or catch(hoặc cả hai):

try {
  for (var object in flybyObjects) {
    var description = await File('$object.txt').readAsString();
    print(description);
  }
} on IOException catch (e) {
  print('Could not describe object: $e');
} finally {
  flybyObjects.clear();
}

Chú ý rằng đoạn code phía trên là bất đồng bộ, try thực hiện trên cả code đồng bộ và code bất đồng bộ async function.

Đọc thêm về exceptions gồm stack traces, rethrow và sự khác nhau giữa Error và Exception

Orther topics

Có nhiều ví dụ code ở Học ngôn ngữThư viện. Bạn cũng có thể xem tại > Dart API reference, Dart API reference nơi chứa nhiều ví dụ