# 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!")), ), ); } } ``` --> 感謝聆聽
{"description":"首次亮相於 2011 年","title":"認識Dart語言","contributors":"[{\"id\":\"c5626a5a-843c-4c05-b9c0-d88068b13f5f\",\"add\":2,\"del\":0},{\"id\":\"6d6e3ba2-6820-4c6f-9117-f09bccc7f7aa\",\"add\":13908,\"del\":4}]"}
    212 views
   owned this note