語法篇
九種內建型別
Numbers (int, double)
Dart 支援兩種 Number 型別:int(整數值) double(雙精度浮點數字)
整型支援傳統的位移操作,移位(<<、>> 和 >>>)、補碼 (~)、按位與 (&)、按位或 (|) 以及按位異或 (^)
assert((3 << 1) == 6); // 0011 << 1 == 0110
assert((3 | 4) == 7); // 0011 | 0100 == 0111
assert((3 & 4) == 0); // 0011 & 0100 == 0000
Strings (String)
使用三個單引號或者三個雙引號也能建立多行字串
在字串中,請以 ${表示式} 的形式使用表示式,如果表示式是一個識別符號(var s = 'string'),可以省略掉 {}
可以使用 + 運算子或並列放置多個字串來連線字串
使用三個單引號或者三個雙引號也能建立多行字串
在字串前加上 r 作為字首建立 “raw” 字串, 則不會被轉義
Booleans (bool)
Lists (也被稱為 arrays)
var list = [1, 2, 3];
在 List 字面量前新增 const 關鍵字會建立一個編譯時常量
var constantList = const [1, 2, 3];
// constantList[1] = 1; // This line will cause an error.
擴充套件運算子(...)和 空感知擴充套件運算子(...?)
var list = [1, 2, 3];
var list2 = [0, ...list];
assert(list2.length == 4);
var list2 = [0, ...?list]; // 如果擴充套件運算子右邊可能為 null
assert(list2.length == 1);
list 的騷操作寫法
var nav = ['Home', 'Furniture', 'Plants', if (promoActive) 'Outlet'];
var listOfInts = [1, 2, 3];
var listOfStrings = ['#0', for (var i in listOfInts) '#$i'];
assert(listOfStrings[1] == '#1');
Sets (Set)
set 是一組特定元素的無序集合
var names = <String>{}; // 建立一個空的 Set
elements.add('fluorine'); // 向已存在的 Set 中新增專案
elements.addAll(halogens);
assert(elements.length == 5) // 使用 .length 可以獲取 Set 中元素的數量
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'}; // 推斷 halogens 變數是一個 Set<String> 型別的集合
// 在 Set 變數前新增 const 關鍵字建立一個 Set 編譯時常量
final constantSet = const {
'fluorine',
'chlorine',
'bromine',
'iodine',
'astatine',
};
// constantSet.add('helium'); // This line will cause an error.
Maps (Map)
Map 是用來關聯 keys 和 values 的物件。其中鍵和值都可以是任何型別的物件。每個 鍵 只能出現一次但是 值 可以重複出現多次(跟js類似,定義/新增鍵值對/獲取值 等)
如果檢索的 Key 不存在於 Map 中則會返回一個 null (js 中返回 undefined)
var gifts = {
// Key: Value
'first': 'partridge',
}
// 可以使用 Map 的構造器建立 Map
var gifts = Map<String, String>();
gifts['first'] = 'partridge';
在一個 Map 字面量前新增 const 關鍵字可以建立一個 Map 編譯時常量(const 對很多型別都是同理)
Map 也可以像 List 一樣支援使用擴充套件運算子(... 和 ...?)以及集合的 if 和 for 操作
Runes (常用於在 Characters API 中進行字元替換)
對於一些特殊字元,表情符號 等 不常用~(Unicode 字元),可以使用 characters 包中定義的 characters
Symbols (Symbol)
可以使用在識別符號前加 # 字首來獲取 Symbol,如 #radix
Symbol 字面量是編譯時常量
The value null (Null)
基本功能
main()
一個特殊且 必須的 頂級函式,Dart 應用程式總是會從該函式開始執行。
var
用於定義變數,透過這種方式定義變數不需要指定變數型別。這類變數的型別 (int) 由它的初始值決定
print()
一種便利的將資訊輸出顯示的方式
int
表示一個整型數字。 Dart 中一些其他的內建型別包括 String、List 和 bool
void
一種特殊的型別,表示一個值永遠不會被使用,以 void 宣告的函式返回型別,並不會返回值
Final 和 Const
定義後不可被更改,一個 final 變數只可以被賦值一次;一個 const 變數是一個編譯時常量(const 變數同時也是 final 的)
它們的區別在於,const比final更加嚴格。final只是要求變數在初始化後值不變,但透過final,我們無法在編譯時(執行之前)知道這個變數的值;而const所修飾的是編譯時常量,我們在編譯時就已經知道了它的值,顯然,它的值也是不可改變的。
final bad = []; //List<int>
bad.add(1); //正常執行,向變數引用物件新增成員
assert
assert() 的呼叫將會在生產環境的程式碼中被忽略掉。在開發過程中,assert(condition) 將會在 條件判斷 為 false 時丟擲一個異常
一些概念
Dart 中一切皆為物件。所有變數引用的都是 物件,每個物件都是一個 類 的例項。數字、函式以及 null 都是物件。除去 null 以外(如果你開啟了 空安全), 所有的類都繼承於 Object 類
空安全:變數在未宣告為可空型別時不能為 null。你可以透過在型別後加上問號 (?) 將型別宣告為可空(跟ts類似)
如果你 明確知道 一個表示式不會為空,但 Dart 不這麼認為時,你可以在表示式後新增 ! 來斷言表示式不為空 如:int x = nullableButNotNullInt!
Dart 是強型別語言,但是在宣告變數時指定型別是可選的,因為 Dart 可以進行型別推斷
如果你想要顯式地宣告允許任意型別,使用 Object。空型別開啟則 Object?
Dart 支援泛型,比如 List<int>(表示一組由 int 物件組成的列表)或 List<Object>(表示一組由任何型別物件組成的列表)
Dart 支援頂級 變數,以及定義屬於類或物件的變數(靜態和例項變數)。例項變數有時稱之為 域 或 屬性。
Dart 支援頂級函式(例如 main 方法),同時還支援定義屬於類或物件的函式(即 靜態 和 例項方法)。你還可以在函式中定義函式(巢狀 或 區域性函式)
Dart 中 表示式 和 語句 是有區別的,表示式有值而語句沒有(跟js其實是一樣的)
一個識別符號以下劃線 (_) 開頭則表示該識別符號在庫內是私有的
如果一個物件的引用不侷限於單一的型別,可以將其指定為 Object(或 dynamic)型別
var name = 'Bob'; // 建立一個變數並將其初始化
Object name = 'Bob'; // 任意型別的 name
String name = 'Bob'; // 指定型別為 String
未初始化以及可空型別的變數擁有一個預設的初始值 null
函式
函式也是物件並且型別為 Function
支援預設引數值定義,沒有指定預設值的情況下預設值為 null
可以將函式賦值給一個變數或者作為其它函式的引數
所有的函式都有返回值。沒有顯示返回語句的函式最後一行預設為執行 return null
定義一個函式
bool isNoble(int atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
// 或
isNoble(atomicNumber) {
return _nobleGases[atomicNumber] != null;
}
如果函式體內只包含一個表示式,你可以使用簡寫語法(箭頭函式)
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
語法 => 表示式 是 { return 表示式; } 的簡寫, => 有時也稱之為 箭頭 函式
引數
有兩種形式的引數:必要引數 和 可選引數。必要引數定義在引數列表前面,可選引數則定義在必要引數後面
命名引數
命名引數預設為可選引數,除非他們被特別標記為 required
定義函式時,使用 {引數1, 引數2, …} 來指定命名引數
void enableFlags({bool? bold, bool? hidden}) {...}
當呼叫函式時,你可以使用 引數名: 引數值 指定一個命名引數的值
enableFlags(bold: true, hidden: false);
使用 required 來標識一個命名引數是必須的引數,此時呼叫者必須為該引數提供一個值
String printUserInfo(String username, {int age=10, String sex="男"}) {//行參
return "姓名:$username---性別:$sex--年齡:$age";
}
String printInfo(String username, {required int age, required String sex}) {//行參
return "姓名:$username---性別:$sex--年齡:$age";
}
匿名函式
大括號中的內容則為函式體
([[型別] 引數[, …]]) {
函式體;
};
const list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});
詞法作用域
變數的作用域在寫程式碼的時候就確定了,大括號內定義的變數只能在大括號內訪問
詞法閉包
閉包 即一個函式物件,即使函式物件的呼叫在它原始作用域之外,依然能夠訪問在它詞法作用域內的變數
/// Returns a function that adds [addBy] to the
/// function's argument.
Function makeAdder(int addBy) {
return (int i) => addBy + i;
}
void main() {
// Create a function that adds 2.
var add2 = makeAdder(2);
// Create a function that adds 4.
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
運算子
絕大多數跟 js 差不多,個例需要注意下
算術運算子
跟 js 類似, but 多了一個 ~/ 除並取整(5 ~/ 2 == 2)
關係運算子
跟 js 類似,but 要判斷兩個物件 x 和 y 是否表示相同的事物使用 == 即可
型別判斷運算子
as、is、is! 運算子是在執行時判斷物件型別的運算子
as
型別轉換(也用作指定 類字首))
is
如果物件是指定型別則返回 true
is!
如果物件是指定型別則返回 false
賦值運算子
可以使用 = 來賦值,同時也可以
= *= %= >>>= ^=
+= /= <<= &= |=
-= ~/= >>=
// 使用 ??= 來為值為 null 的變數賦值
b ??= value;
// 使用賦值以及複合賦值運算子
var a = 2; // Assign using =
a *= 3; // Assign and multiply: a = a * 3
assert(a == 6);
邏輯運算子
!表示式 對錶達式結果取反(即將 true 變為 false,false 變為 true)
|| 邏輯或
&& 邏輯與
& 按位與
| 按位或
^ 按位異或
~表示式 按位取反(即將 “0” 變為 “1”,“1” 變為 “0”)
<< 位左移
位右移
無符號右移
條件表示式
兩個特殊的運算子
條件 ? 表示式 1 : 表示式 2
表示式 1 ?? 表示式 2
如果表示式 1 為非 null 則返回其值,否則執行表示式 2 並返回其值
級聯運算子
級聯運算子 (.., ?..) 可以讓你在同一個物件上連續呼叫多個物件的變數或方法 --不是很理解
流程控制語句
與 js 類似 不作贅述
類
詳見:https://dart.cn/guides/langua...
泛型
https://dart.cn/guides/langua...