Flutter開發之Dart語法基礎
-
Dart
是谷歌在 2011 年推出的程式語言,是一種結構化Web
程式語言,允許使用者通過Chromium
中所整合的虛擬機器(Dart VM
)直接執行Dart
語言編寫的程式,免去了單獨編譯的步驟 - 以後這些程式將從
Dart VM
更快的效能與較低的啟動延遲中受益 -
Dart
從設計之初就為配合現代web
整體運作而考慮,開發團隊也同時在持續改進Dart
向JavaScript
轉換的快速編譯器 -
Dart VM
以及現代JavaScript
引擎(V8 等)都是Dart
語言的首選目標平臺 -
Dart
語言和Swift
語言有很多的相似之處
重要概念
在學習 Dart
語言之前, 先了解一些 Dart
相關的一些概念:
- 在
O-Objective
中有一切皆物件的說法, 這句話在Dart
中同樣適用- 所有能夠使用變數引用的都是物件, 每個物件都是一個類的例項
- 在
Dart
中 甚至連 數字、方法和null
都是物件 - 所有的物件都繼承於
Object
類
-
Dart
動態型別語言, 儘量給變數定義一個型別,會更安全,沒有顯示定義型別的變數在debug
模式下會型別會是dynamic
(動態的) -
Dart
會在執行之前解析你的所有程式碼,指定資料型別和編譯時的常量,可以提高執行速度 -
Dart
中的類和介面是統一的,類即介面,你可以繼承一個類,也可以實現一個類(介面),自然也包含了良好的面向物件和併發程式設計的支援 -
Dart
函式main()
- 類似的,
Dart
支援頂級變數,以及依賴於類或物件(靜態變數和例項變數)變數。例項變數有時被稱為域或屬性 -
Dart
不具備關鍵字public
,protected
和private
。如果一個識別符號以下劃線(_)
開始,那麼它和它的庫都是私有的 - 識別符號可以字母或(_)開始,或者是字元加數字的組合開頭
以上只是大概說明了一些 Dart
中的重要概念, 具體的語法使用, 請看下文
基本語法
註釋
Dart
的註釋分為3種:單行註釋、多行註釋、文件註釋
- 單行註釋以
//
開頭 - 多行註釋以
/*
開頭,以*/
結尾 - 文件註釋以
///
或者/**
開頭
分號;
Dart Dart
其他語法
Dart print(Object)
變數和常量
變數
使用 var
、 Object
或 dynamic
關鍵字宣告變數
var name = 'name'; dynamic name1 = 'name1'; String name2 = 'name2'; // 變數的賦值 name = 'a'; name1 = 'a1'; name2 = 'a2';
未初始化的變數的初始值為 null
, 即使是數字也是如此,因為在 Dart
中數字也是一個物件
var name; dynamic name1; String name2;
可選型別
在宣告變數的時候,你可以選擇加上具體的型別:
String name2 = 'name2';
這種方式可以更加清晰的表達你想要定義的變數的型別, 編譯器也可以根據該型別為你提供程式碼補全、提前發現 bug 等功能
注意
對於區域性變數,這裡遵守 程式碼風格推薦 部分的建議,使用 var
而不是具體的型別來定義區域性變數
常量
- 常量使用
final
或者const
- 一個
final
變數只能賦值一次 - 一個
const
變數是編譯時常量 - 例項變數可以為
final
但是不能是const
final
final
修飾的變數(即常量2)
final age = 10; final int age1 = 20; // final修飾的變數不能重新賦值, 會報錯 age = 20; age1 = 30;
const
-
const
變數為編譯時常量 - 如果在類中使用
const
定義常量,請定義為static const
- 使用
const
定義的常量, 可以直接給定初始值,也可以使用其他const
變數的值來初始化其值
// const const m1 = 12; const double m2 = 23; const m3 = m1 + m2; // final修飾的變數不能重新賦值, 會報錯 m1 = 10; m2 = 1.02;
操作符
算術操作符
Dart
支援常用的算術操作符
操作符 | 解釋 |
---|---|
+ |
加號 |
– |
減號 |
-expr |
負號 |
* |
乘號 |
/ |
除號(值為 double 型別) |
~/ |
除號,但是返回值為整數 |
% |
取模 |
示例:
assert(2 + 3 == 5); assert(2 - 3 == -1); assert(2 * 3 == 6); assert(5 / 2 == 2.5);// 結果是double型別 assert(5 ~/ 2 == 2);// 結果是integer型別 assert(5 % 2 == 1);// 餘數
自加自減
Dart
還支援自加自減操作
++var var++ --var var--
示例
var a = 0, b = 0; b = a++; print('a = $a, b = $b'); //a = 1, b = 0 b = ++a; print('a = $a, b = $b'); //a = 2, b = 2 b = a--; print('a = $a, b = $b'); //a = 1, b = 2 b = --a; print('a = $a, b = $b'); //a = 0, b = 0
關係操作符
運算子 | 含義 |
---|---|
== |
等於 |
!= |
不等於 |
> |
大於 |
< |
小於 |
>= |
大於等於 |
<= |
小於等於 |
== identical()
external bool identical(Object a, Object b);
型別判定操作符
型別判定操作符是在執行時判定物件型別的操作符
操作符 | 解釋 |
---|---|
as |
型別轉換 |
is |
如果物件是指定的型別返回 True |
is! |
如果物件是指定的型別返回 False |
- 只有當
obj
實現了T
的介面,obj is T
才是true
。例如obj is Object
總是true
- 使用
as
操作符把物件轉換為特定的型別 - 可以把
as
它當做用is
判定型別然後呼叫 所判定物件的函式的縮寫形式
if (emp is Person) { // Type check emp.firstName = 'Bob'; } // 上面程式碼可簡化為 (emp as Person).firstName = 'Bob';
注意
如果 emp
是 null
或者不是 Person
型別,則第一個示例使用 is
則不會執行條件裡面的程式碼,而第二個情況使用 as
則會丟擲一個異常; 所以在不缺定 emp
是否為空的情況下, 安全起見, 建議使用第一種方式
賦值操作符
= |
–= |
/= |
%= |
>>= |
^= |
|
+= |
*= |
~/= |
<<= |
&= |
示例:
// 給 a 變數賦值 a = value; // 複合賦值操作符 a += b;// 等價於a = a + b; // 如果 b 是 null,則賦值給 b; // 如果不是 null,則 b 的值保持不變 b ??= value; // 如下所示: var s; print(s);// null print(s ?? 'str');// str s ??= 'string'; print(s);// string
邏輯操作符
可以使用邏輯操作符來 操作布林值:
!expr || &&
條件表示式
condition ? expr1 : expr2 // 如果 condition 是 true,執行 expr1 (並返回執行的結果); 否則執行 expr2 並返回其結果 expr1 ?? expr2 // 如果 expr1 是 non-null,返回其值; 否則執行 expr2 並返回其結果
示例:
String toString() => msg ?? super.toString(); // 上面的程式碼等價於 String toString() => msg == null ? super.toString() : msg; // 等價於 String toString() { if (msg == null) { return super.toString(); } else { return msg; } }
級聯操作符
級聯操作符 ( ..
) 可以在同一個物件上 連續呼叫多個函式以及訪問成員變數。 使用級聯操作符可以避免建立 臨時變數, 並且寫出來的程式碼看起來 更加流暢
querySelector('#button') // Get an object. ..text = 'Confirm'// Use its members. ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!'));
第一個方法 querySelector()
返回了一個 selector
物件。 後面的級聯操作符都是呼叫這個物件的成員, 並忽略每個操作 所返回的值
// 上面程式碼等價於 var button = querySelector('#button'); button.text = 'Confirm'; button.classes.add('important'); button.onClick.listen((e) => window.alert('Confirmed!'));
級聯呼叫也可以巢狀:
final addressBook = (new AddressBookBuilder() ..name = 'jenny' ..email = '[email protected]' ..phone = (new PhoneNumberBuilder() ..number = '415-555-0100' ..label = 'home') .build()) .build();
注意
嚴格來說,兩個點的級聯語法不是一個操作符, 只是一個 Dart
特殊語法。
流程控制語句
在 Dart
中可以使用下面的語句來控制 Dart
程式碼的流程:
-
if-else
-
for
和for-in
-
while
和do-while
-
switch
-
assert
-
break
和continue
-
try-catch
和throw
if-else
Dart
支援 if
語句以及可選的 else
if (a == 0) { print('a = 0'); } else if (a == 1) { print('a = 1'); } else { print('a = 2'); }
注意
上述程式碼中的條件控制語句的結果必須是布林值
for
可以使用標準的 for
迴圈, List
和 Set
等實現了 Iterable
介面的類還支援 for-in
形式的遍歷:
var arr = [0, 1, 2]; // for迴圈 for (var i = 0; i < arr.length; i++) { print(arr[i]); } // for-in迴圈 for (var x in arr) { print(x); }
While
和 do-while
// while 迴圈在執行迴圈之前先判斷條件是否滿足: while (c == 0) { print('c = $c'); } // 而do-while迴圈是先執行迴圈程式碼再判斷條件: do { print('c = $c'); } while (c == 0);
Break
和 continue
使用 break
來終止迴圈:
while (true) { if (shutDownRequested()) break; processIncomingRequests(); }
使用 continue
來開始下一次迴圈
for (int i = 0; i < candidates.length; i++) { var candidate = candidates[i]; if (candidate.yearsExperience < 5) { continue; } candidate.interview(); }
Switch
-
Dart
中的Switch
語句使用==
比較integer
、string
、或者編譯時常量 - 比較的物件必須都是同一個類的例項, 比較適合列舉值
- 每個非空的
case
語句都必須有一個break
語句 - 另外還可以通過
continue
、throw
或者return
來結束非空case
語句 - 當沒有
case
語句匹配的時候,可以使用default
語句來匹配這種預設情況 - 每個
case
語句可以有區域性變數,區域性變數只有在這個語句內可見
var command = 'OPEN'; switch (command) { case 'CLOSED': print('CLOSED'); break; case 'APPROVED': print('APPROVED'); // break; // 這裡非空的case, 沒有break會報錯 case 'DENIED': // 這裡空的case, 可以不要break case 'OPEN': print('OPEN'); continue nowClosed; //如果你需要實現這種繼續到下一個 case 語句中繼續執行,則可以 使用 continue 語句跳轉到對應的標籤(label)處繼續執行: nowClosed: case 'PENDING': print('PENDING'); break; default: print('default'); }
Assert
assert assert true false
// Make sure the variable has a non-null value assert(text != null); // Make sure the value is less than 100 assert(number < 100); // Make sure this is an https URL assert(urlString.startsWith('https'));
注意
斷言只在開發模式下執行有效,如果在生產模式 執行,則斷言不會執行
這篇文章的簡單介紹就到這裡了, 下一篇將會記錄 Dart
的基本資料型別