# Flutter - Dart語言學習
## 優勢
* 採用JIT模式,這樣就避免了每次改動都要進行編譯,極大的節省了開發時間
* Flutter中需要能夠在每個動畫幀中執行大量的程式碼。這意味着需要一種既能提供高效能的語言,而不會出現會丟幀的週期性暫停,而Dart支援AOT,在這一點上可以做的比JavaScript更好。
* Dart是型別安全的語言,支援**靜態型別檢測**,所以可以在編譯前發現一些型別的錯誤,並排除潛在問題,(JavaScript是一個弱型別語言)
## 介紹
### 基本資料型態
* int 整數
* double 浮點數
* bool 布林值
* string 字串
* 兩個單引號 ' ' 或兩個雙引號 " "包圍的內容
* 跳脫字元須在前面加\,例如: 印出`"` ,就必須前面加反斜線 `\"`
* String interpolation,$variableName or ${variableName}(有無大括號都可)
```dart
print('年齡: ${age});
```
* num 數值
* 有兩種型態,同時表示整數/浮點數,給予初始值後從整數變為福點數是允許的
* List
* 為集合資料型別,可以想成`array`,有順序性
```dart
List list2 = [1, 2, 3];
List<int> list3 = [1, 2, 3]; //規定型態
var list4 = List(3); //固定長度
```
* Map
* 使用key-value的方式來儲存的資料型態,key 和value 可以是任何型別的物件
* key 是唯一
```dart
//等於 var map2 = {};
var map2 = Map();
// 新增新的一對 key-value
map2['first'] = 'a';
//限制Map型態
Map<int,String> map3 = const {
2: 'a',
10: 'b',
18: 'c',
};
```
* Runes
* 代表字串的UTF-32 code points
* [可參考此網站](http://www.unicode.org/emoji/charts/full-emoji-list.html)查找其他表情符號
```dart
Runes input = Runes('\u{1f605}');
debugPrint(String.fromCharCodes(input));
```

### 變數 & 常數
#### 命名規則
* Code Style 推薦使用**lowerCamelCase**,可參考官網lowerCamelCase
第一個字不能為數字 ( 例如:int 1x = 0; )
* 大小寫視為不同
* 不能包含特殊符號,除了 _ 和 $
* 不能命名為Dart 的[保留字](https://dart.dev/guides/language/language-tour#variables)
#### 變數
* var
* 會自動推斷其資料型別
* 賦予初始值後型別不可以被改變,
```dart
void main() {
var word = "hello";
word = 1000; //報錯
}
```
```console
Error: A value of type 'int' can't be assigned to a variable of type 'String'.
word = 1000; //報錯
^
```
* Object
* 賦予初始值後型別可以被改變
```dart
void main() {
Object x = 'Hello Object';
x = 1000;
}
```
* 只能使用Object的屬性與方法, 否則編譯器會報錯。
```dart
Object b;
main() {
b = "";
printLengths();
}
printLengths() {
print(b.length);
}
```
```console
Error: The getter 'length' isn't defined for the class 'Object'.
- 'Object' is from 'dart:core'.
print(b.length);
^^^^^^
```
* dynamic
* 賦予初始值後型別可以被改變
```dart
void main() {
dynamic t = "hi world";
t = 1000;
}
```
* 編譯器會提供所有可能的組合
```dart
dynamic a;
main() {
a = "";
printLengths();
}
printLengths() {
print(a.length);
}
```
#### 常數
* final和const
* final: 變數在第一次使用時被初始化,其值在初始化後不可改變
* const: 比final更加嚴格,必須在編譯之前就是明確的資料值
* 兩者都可以省略型別
```dart
//可以省略String這個型別宣告
final str = "hi world";
//final String str = "hi world";
const str1 = "hi world";
//const String str1 = "hi world";
```
### 所有型別都是Object的子類(包括Function和Null)
### [null safety](https://dart.dev/null-safety)
* 適用於 Dart 2.12 加 Flutter 2後,除非你明確告訴 Dart 一個變量可以為空,否則它被認定是不可為空的。
* 允許null
```dart
int? aNullableInt = null;
```
* 檢查是否為null
```dart
if (t?.creationDate?.millisecond != null) {
}
```
相當於JS語法
```javascript
if (t && t.creationDate && t.creationDate.millisecond) {
}
```
### 沒有public, protected, and private
* 當你要使function或是變數為private時只需要在名稱前加上`_`即可,這樣能防止變數被其他地方存取。 [簡易範例1](https://tw511.com/a/01/7928.html) [簡易範例2](https://stackoverflow.com/questions/17488611/how-to-create-private-variables-in-dart)
## 繼承
* 使用時機:多個class,有共同的屬性與規則
* 一個類別使用`extends`關鍵字來從另一個類別繼承,一個子類別只能繼承一個父類別
### 參考資料
https://ithelp.ithome.com.tw/articles/10241767
## 多型
### 參考資料
https://ithelp.ithome.com.tw/articles/10241767
## 類別
* 新增物件,以下兩種宣告方式是一樣意思
* 類別 物件名稱 = new 類別名([引數值]),Call by reference,等號左右兩邊的類別(class)要一樣或有繼承關係才可以
* 類別 物件名稱 = 類別名([引數值])
* 建構式 ( constructors )
* 新增一個物件時最後會執行的步驟,故物件初始化時,想傳值、對資料做處理或額外的判斷,可做在建構式裡面
* 名字必須與類別名稱一樣
```dart
class User {
String name;
int age;
User({
required this.name,
required this.age,
});
}
```
### abstract(抽象類別)
可以想成這是一個模板沒有實際內容,所以有繼承他的子類別就要把父類別的抽象方法都實作出來
1. 一定會有抽象方法(只有方法名,無內容)
2. 只要有一個抽象方法,類別一定也要改為抽象,變成抽象類別後,本身無法實體化,即無法被 new,只剩提供繼承的功能,去當父類別的角色,或做為宣告的類別。
3. 繼承抽象類別的子類別
* 一定要將父類別的抽象方法都實作出來 (父類別的所有抽象方法都要被override),才可編譯
```dart
// 這個類是抽象類,不能實體化
abstract class AbstractContainer {
// 定義建構式、變數、方法等等
void updateChildren(); // 抽象方法.
void show() {
print('AbstractContainer show');
}
}
//子類別
class SpecializedContainer extends AbstractContainer {
// 定義更多的建構式、變數、方法等等
//一定要將父類別的抽象方法都實作
@override
void updateChildren() {
print('SpecializedContainer implement updateChildren');
}
}
main() {
SpecializedContainer s = SpecializedContainer();
s.updateChildren(); //印出 SpecializedContainer implement updateChildren
s.show(); //印出 AbstractContainer show
}
```
## interface(介面)
## 線上編譯器
https://dart.dev/#try-dart
## 參考資料
https://dart.cn/guides/language/language-tour
https://tw511.com/a/01/7928.html
https://ithelp.ithome.com.tw/articles/10242009
###### tags: `flutter` `dart`