從 0 開始學 Dart:完整語法、應用範例與即時測驗

Dart 是一個強型別、支援 Null Safety、具備物件導向與非同步能力的現代程式語言, 常見於 Flutter,也能用於 CLI、伺服器與一般程式開發。本網站詳細整理出Dart 初學到進階入門的重要主題,包含變數、函式、集合、類別、非同步與 Dart 3 特性, 並搭配互動式題庫與即時評分系統,幫助你邊學邊驗證理解程度。

1

安裝與執行 Dart

你可以如何執行 Dart

  • 使用 DartPad 線上執行
  • 安裝 Dart SDK 後在終端機執行
  • 使用 Flutter 專案時撰寫 Dart
初學者建議先用 DartPad 熟悉基本語法。

第一個 Dart 程式

void main() {
  print('Hello, Dart!');
}

每個 Dart 程式都從 main() 開始執行。

常用指令

指令 用途
dart run 執行 Dart 程式
dart create my_app 建立新 Dart 專案
dart analyze 靜態分析程式碼
dart format . 格式化程式碼
2

基礎語法

強型別

Dart 是強型別語言,但支援型別推論,因此程式碼可讀性與簡潔度兼具。

萬物皆物件

數字、函式甚至 null 都是物件。

Null Safety

可在編譯階段降低空值取用錯誤。

輸出與註解

void main() {
  // 單行註解
  /*
    多行註解
  */
  print('歡迎來到 Dart 教學');
}
3

變數、型別與 Null Safety

變數宣告方式

void main() {
  var name = 'Alice';
  String city = 'Taipei';
  Object value = 123;
  dynamic any = '可動態改變';

  any = 999;
  print('$name 來自 $city,value = $value,any = $any');
}

final、const、late

final today = DateTime.now();
const pi = 3.14159;
late String description;

void main() {
  description = '這是一段晚點才設定的文字';
  print(description);
}

Null Safety 核心觀念

寫法 意義 說明
String name 不可為 null 使用前必須初始化
String? name 可為 null 可存字串或 null
user?.name 安全呼叫 左值為 null 時不報錯
name! 非空斷言 你明確告訴編譯器它不是 null
void main() {
  String? nickname;
  print(nickname); // null

  String username = 'dart_user';
  print(username.length);

  String? email;
  print(email?.length); // null
}
注意: ! 若使用不當,執行期仍可能發生錯誤。
4

函式與參數設計

基本函式與箭頭語法

int add(int a, int b) {
  return a + b;
}

int multiply(int a, int b) => a * b;

void main() {
  print(add(3, 5));
  print(multiply(4, 6));
}

命名參數與可選參數

String greet({required String name, String title = '同學'}) {
  return '你好,$title $name';
}

String buildMessage(String text, [String suffix = '!']) {
  return text + suffix;
}

void main() {
  print(greet(name: '小明'));
  print(greet(name: '小華', title: '老師'));
  print(buildMessage('歡迎來到 Dart'));
}

匿名函式與高階函式

void main() {
  final numbers = [1, 2, 3, 4, 5];

  final squares = numbers.map((n) {
    return n * n;
  }).toList();

  numbers.forEach((n) => print('數字:$n'));
  print(squares);
}
Dart 的函式是第一級公民,可以被指派、傳遞、回傳。
5

流程控制與集合

if、for、while、switch

void main() {
  int score = 85;

  if (score >= 90) {
    print('A');
  } else if (score >= 80) {
    print('B');
  } else {
    print('C');
  }

  for (int i = 1; i <= 3; i++) {
    print('for 迴圈第 $i 次');
  }

  int count = 0;
  while (count < 2) {
    print('while: $count');
    count++;
  }

  String role = 'admin';
  switch (role) {
    case 'admin':
      print('管理員');
      break;
    case 'user':
      print('一般使用者');
      break;
    default:
      print('未知角色');
  }
}

List

final fruits = ['apple', 'banana', 'orange'];
fruits.add('grape');
print(fruits[0]);

Set

final ids = {1, 2, 2, 3};
print(ids); // {1, 2, 3}

Map

final user = {
  'name': 'Amy',
  'age': 20,
};
print(user['name']);

Collection if / for / spread

void main() {
  bool vip = true;
  final baseMenu = ['首頁', '商品'];
  final tags = ['dart', 'flutter'];

  final menu = [
    ...baseMenu,
    if (vip) 'VIP專區',
    for (final tag in tags) '#$tag',
  ];

  print(menu);
}
這些集合語法在 Flutter UI 建構中尤其常見。
6

類別與物件導向

類別、屬性與方法

class Student {
  String name;
  int age;

  Student(this.name, this.age);

  void introduce() {
    print('我是 $name,今年 $age 歲');
  }
}

void main() {
  final s = Student('小明', 18);
  s.introduce();
}

命名建構子

class Product {
  String name;
  double price;

  Product(this.name, this.price);

  Product.free(String name) : this(name, 0);

  void show() => print('$name: $price');
}

void main() {
  final p = Product.free('試用品');
  p.show();
}

繼承、抽象類別、implements

abstract class Animal {
  void speak();
}

class Dog extends Animal {
  @override
  void speak() {
    print('汪汪');
  }
}

class Cat implements Animal {
  @override
  void speak() {
    print('喵喵');
  }
}

void main() {
  Animal dog = Dog();
  Animal cat = Cat();

  dog.speak();
  cat.speak();
}
extends 偏向繼承實作,implements 偏向實作介面契約。
7

Dart 3 新特性

Records

方便一次回傳多個值。

Patterns

可做結構匹配與解構。

Enhanced Enums

Enum 可有欄位、建構子與方法。

Records 範例

(String, int) getUser() {
  return ('Alice', 20);
}

void main() {
  final user = getUser();
  print(user.$1);
  print(user.$2);

  final (name, age) = getUser();
  print('$name - $age');
}

Pattern Matching 範例

void checkValue(Object value) {
  switch (value) {
    case int n when n >= 60:
      print('整數且及格:$n');
      break;
    case int n:
      print('整數但未及格:$n');
      break;
    case String s:
      print('字串:$s');
      break;
    default:
      print('其他型別');
  }
}

void main() {
  checkValue(88);
  checkValue(30);
  checkValue('Hello');
}

Enhanced Enum 範例

enum Level {
  beginner('初學者'),
  intermediate('中階'),
  advanced('進階');

  final String label;
  const Level(this.label);
}

void main() {
  print(Level.beginner.label);
}
8

非同步程式設計:Future、async、await、Stream

Future、async、await

Future<String> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  return '資料下載完成';
}

void main() async {
  print('開始下載...');
  final result = await fetchData();
  print(result);
}

錯誤處理

Future<int> divideAsync(int a, int b) async {
  await Future.delayed(Duration(milliseconds: 500));
  if (b == 0) throw Exception('除數不可為 0');
  return a ~/ b;
}

void main() async {
  try {
    final result = await divideAsync(10, 0);
    print(result);
  } catch (e) {
    print('發生錯誤:$e');
  }
}

Stream

Stream<int> countStream() async* {
  for (int i = 1; i <= 3; i++) {
    await Future.delayed(Duration(seconds: 1));
    yield i;
  }
}

void main() async {
  await for (final value in countStream()) {
    print('收到:$value');
  }
}

Future 偏一次結果,Stream 偏持續資料流。

9

範例應用

範例一:成績等第判斷器

String getGrade(int score) {
  if (score >= 90) return 'A';
  if (score >= 80) return 'B';
  if (score >= 70) return 'C';
  if (score >= 60) return 'D';
  return 'F';
}

void main() {
  final scores = [95, 82, 76, 61, 40];
  for (final s in scores) {
    print('分數 $s => ${getGrade(s)}');
  }
}

範例二:簡易待辦清單模型

class Todo {
  String title;
  bool done;

  Todo(this.title, {this.done = false});

  void toggle() {
    done = !done;
  }

  @override
  String toString() => '[${done ? 'x' : ' '}] $title';
}

void main() {
  final todos = [
    Todo('學 Dart'),
    Todo('寫 Flutter'),
    Todo('完成作業'),
  ];

  todos[0].toggle();

  for (final todo in todos) {
    print(todo);
  }
}

範例三:模擬 API 讀取使用者資料

Future<Map<String, dynamic>> fetchUser() async {
  await Future.delayed(Duration(seconds: 1));
  return {
    'name': 'Dart Learner',
    'level': 'beginner',
    'points': 120,
  };
}

void main() async {
  final user = await fetchUser();
  print('名稱:${user['name']}');
  print('等級:${user['level']}');
  print('點數:${user['points']}');
}

建議學習順序

  1. 先理解 main()、輸出、變數與基本型別
  2. 再學函式、命名參數、匿名函式
  3. 熟悉 List / Set / Map 與流程控制
  4. 進入 class、constructor、繼承與抽象類別
  5. 最後掌握 async / await、Stream 與 Dart 3 特色
10

互動式 Dart 題庫與即時評分系統

題庫功能

題目涵蓋基礎語法、Null Safety、函式、集合、物件導向、非同步與 Dart 3。 每題作答後會立即顯示對錯與解析,並同步更新總分、正確率與進度。

已作答
0
答對題數
0
正確率
0%
剩餘題數
0
尚未產生總評。完成幾題後按「查看總評」即可看到整體表現與建議。
11

學習資源