owned this note
owned this note
Published
Linked with GitHub
---
title: Flutter 開發實戰 之 認識 Dart 語言
slideOptions:
theme: white
transition: zoom
---
# Flutter 開發實戰
## 認識 Dart 語言
##### 以下內容部分取自 https://www.dartcn.com/guides/language/language-tour#variables
---
## Dart 語言的前世今生
- 首次亮相於 2011 年
- 由 Google 開發
- 目標:解決 Web 開發問題,如:
- **JavaScript** 的動態特性
- 更強的物件模型,支援模組化與可擴展程式設計
---
## Dart 語言的特性
* ✅ **執行速度快**
* ✅ **易於移植** (可編譯為 ARM & x86)
* ✅ **支援 iOS、Android、Web、Desktop**
* ✅ **易於閱讀**
---
## Dart 重要概念
----
- 任何保存在變數中的都是一個對象, 而所有的對像都是對應一個類別的實例。 無論是數字,函數和null都是物件。所有物件繼承自`Object`別。
- Dart 是強型別語言,但能自動推斷類型(`var`)因此類型註釋可選。若不限定類型,可使用 dynamic。
- 支援泛型,如 ```List<int>```(整數列表)、```List<dynamic>```(任意類型列表)。
----
- 沒有 public、protected、private 關鍵字,以下劃線 _ 開頭的標識符表示庫內私有。
- Dart 語法區分表達式與語句:
* 表達式有運行時值(如 condition ? expr1 : expr2)。
* 語句沒有值(如 if-else)。
- Dart 提示警告與錯誤:
* 警告不影響執行,但可能導致問題。
* 錯誤可分為編譯時錯誤(阻止執行)與執行時錯誤(導致異常)。
---
## 第一個 Dart 程式
第一個程式肯定是要來 Hello World 一下的吧
```dart=
void main() {
print('Hello, World!');
}
```
---
## Dart 內建類型 與 宣告
我知道這很廢...
----
### 內建類型
#### 1️⃣ 數字num `int`、`double`
```dart
int age = 42;
double pi = 3.14;
```
#### 2️⃣ 字串 `String`
```dart
String greeting = "Hello";
```
#### 3️⃣ 布林值 `bool`
```dart
bool isTrue = true;
```
----
#### 4️⃣ 列表 `List<T>` (有序集合)
```dart
List<int> numbers = [1, 2, 3, 4, 5];
```
#### 5️⃣ 集合 `Set<T>` (無序不重複)
```dart
Set<String> uniqueNames = { 'Alice', 'Bob' };
```
#### 6️⃣ 映射 `Map<K, V>` (鍵值對)
```dart
Map<String, int> ages = { 'Alice': 30, 'Bob': 25 };
```
#### 7️⃣ 空值 `null`
```dart
int? nullableNumber = null;
```
----
### 變數與類型
- 類型推斷是Dart提高程式碼簡潔性和開發效率的重要機制。
- Dart的空安全性讓使用者在編譯時更能察覺到潛在的null錯誤,增強可靠性。
- 未初始化的變數預設值是null。(即使變數是num預設值也是null)
----
#### var 保留字
允許 Dart 自動推斷類型 :
```Dart=
var pi = 3.14; //Dart 推斷 pi 為 double
var dinner = "蚊香牛肉麵"; //Dart 推斷 dinner 為 String
var isMale = true; //Dart 推斷 isMale 為 boolean
```
但如果是這樣 :
```Dart=
void main() {
var pi = "3.14";
pi = 3.14; //報錯 : main.dart:3:8: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
print(pi);
}
```
----
#### 明確類型宣告
可以直接使用類型名做變數宣告
但如果類型可從附值時推斷,官方建議用var。
```dart=
// 直接指定型別
String greeting = "Hello";
```
----
#### 特殊類型 : dynamic
<!-- 和 Object -->
----
#### dynamic
- 預設「禁用類型檢查」,變數可以是任意類型的值。
- 錯誤風險較高。
```dart
dynamic number = "1234"; //此時類型是String
number = 1234; //改變類型為int,不會報錯。
//如果是var呢
var number = "1234";
number = 1234; //不能改變類型
```
----
<!-- #### Object
- 所有類型的共同基礎、父類別,支援類型檢查。
- 可安全使用通用方法。
```dart
Object number = "1234";
number = 1234; //和dynamic一樣不會報錯
```
---- -->
<!-- #### dynamic vs Object
* dynamic比較靈活但是不安全。
* Object 無法使用類型自帶的方法。
---- -->
<!-- 舉例 :
```dart
// isEmpty 是 String 的方法
dynamic a = "你好";
print(a.isEmpty);//可以使用
Object b = "早安";
print(b.isEmpty); //錯誤 : Error: The getter 'isEmpty' isn't defined for the class 'Object'.
```
---- -->
<!-- #### dynamic and var
當var無預設值時會判定為dynamic
```dart
var number;
number = "123";
print(number.runtimeType);
number = 123;
print(number.runtimeType);
//這樣子不會有錯誤產生
```
---- -->
#### final 和 const
- 用於宣告不可改變的變數
- 可幫助確認該變數不該被修改
- 助於減少記憶體浪費
- 差別 :
- final:運行時才給變數賦值。
- const:編譯時就要確定值。
----
舉例
```dart
final pi = 3.14;
pi = 3.1415926; //錯誤 : Error: Can't assign to the final variable 'pi'.
const pi = 3.14;
pi = 3.1415926;//錯誤 : Error: Can't assign to the const variable 'pi'.
```
----
#### Null Safety
有時候不想馬上附值,變數宣告會一直有null的錯誤,這時null Safety救派上用場啦~
```dart
String number;
print(number);//錯誤 : Error: Non-nullable variable 'number' must be assigned before it can be used.
String? number;
print(number);//這樣就可以
```
---
## 函式 (Function)
函式是啥?可以吃嗎?
----
<!-- ## 簡介
Dart 是一門真正物件導向的語言, 甚至其中的函數也是對象,並且有它的型別 Function。 這也意味著函數可以被賦值給變數或作為參數傳遞給其他函數。 也可以把Dart 類別的實例當作方法來呼叫。
---- -->
#### 宣告方式 :
```dart
int add(int a, int b) {
return a + b;
}
```
#### 更簡潔的方法:箭頭函式
```dart
int add(int a, int b) => a + b;
```
----
#### 可選參數
* 可選參數顧名思義就是不一定要填寫的參數
* 分為 `命名可選參數` 以及 `位置可選參數` ,但一個參數只能選擇其中一種方式修飾。
----
#### 命名可選參數
```dart
void worship({required String name, String? sentence}){
sentence ??= '好電';
print('$name $sentence');
}
//或者是
void worship({required String name, String sentence = "好電"}){
print('$name $sentence');
}
//錯誤示範
void worship({required String name, String sentence}){
sentence ??= '好電';
print('$name $sentence');
}
```
----
#### 位置可選參數
```dart
void greet(String name , [String? greeting]){
greeting ??= 'hello';
print('$greeting , $name');
}
//或者是
void greet(String name , [String greeting = "hello"]){
print('$greeting , $name');
}
//錯誤示範
void greet(String name , [String greeting]){
greeting ??= 'hello';
print('$greeting , $name');
}
```
----
#### 匿名函數 :
沒有名字的函數,這種函數稱為匿名函數
```dart
//舉例
var list = [ 'apples' , 'bananas' , 'oranges' ];
list.forEach (( item ) {
print('${list.indexOf(item)}: $item');
});
//也可以用箭頭函數的方式
var list = [ 'apples' , 'bananas' , 'oranges' ];
list.forEach((item) => print('${list.indexOf(item)}: $item'));
```
---
## 泛型 (Generics)
----
### 什麼是泛型?
- 假設有一個箱子,裡面可以裝東西
- 但如果沒有限制內容物,可能會很混亂!
- 使用泛型可讓類別、方法支援不同類型
----
### 舉例來說
```dart
List<T> createList<T>(T item) {
return [item];
}
```
----
### 泛型在類別中的應用
- 除了函式,類別也可以使用泛型,以提高靈活性和可重用性。
- **示例:泛型類別**
```dart
class Box<T> {
T value;
Box(this.value);
}
void main() {
Box<int> intBox = Box(10);
Box<String> strBox = Box("Hello");
print(intBox.value); // 10
print(strBox.value); // Hello
}
```
----
### 泛型的約束(型別界限)
- 可以使用 `extends` 來限制泛型的類型,使其只能接受某些類型的子類別。
- **示例:限制為 `num` 類型**
```dart
class Calculator<T extends num> {
T add(T a, T b) {
return (a + b) as T;
}
}
void main() {
Calculator<int> intCalc = Calculator();
print(intCalc.add(5, 10)); // 15
// Calculator<String> strCalc = Calculator(); // ❌ 錯誤,String 不是 num
}
```
----
## 泛型方法
- **如果類別不是泛型的,仍然可以在方法中使用泛型。**
- **示例:泛型方法**
```dart
class Utility {
static T getFirst<T>(List<T> items) {
return items[0];
}
}
void main() {
print(Utility.getFirst([10, 20, 30])); // 10
print(Utility.getFirst(["A", "B", "C"])); // A
}
```
---
<!--
# Dart 的異步編程 (async / await)
### Dart 使用 `Future` 來處理異步操作
- **async / await** 讓程式更易讀
- 常見應用:
✅ 等待網路請求
✅ 讀寫檔案
✅ 延遲操作
---
```dart
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 2));
return "資料載入完成";
}
void main() async {
print("開始載入...");
String result = await fetchData();
print(result);
}
```
--- -->
<!-- # Flutter Widget 基礎介紹
### Flutter 主要由 **Widget** 組成,可分為:
- **無狀態 Widget (`StatelessWidget`)**
- 不會變動,固定顯示內容
- **有狀態 Widget (`StatefulWidget`)**
- 會隨著互動改變畫面
```dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Flutter App")),
body: Center(child: Text("Hello, Flutter!")),
),
);
}
}
``` -->
感謝聆聽