Flutter準備篇之Dart語言初探


Flutter準備篇之Dart語言初探


什麼是Dart

Dart 是一種跨平臺的客戶端開發語言。具有專門為客戶端優化、高生產力、快速高效、可移植易學的風格。Dart主要由Google負責開發和維護

重要概念

  • 在 Dart 中 甚至連 數字、方法和 null 都是對象。所有的對象都繼承於 Object 類
  • Object所有Dart對象的基類,所以每個其他Dart類都是Object的子類,Object在編譯時檢查類型
  • 雖然dart語言通過var進行運行時類型推導,但是Dart是強類型的語言,類型一旦確定就不可以改變
  • Dart 沒有 public、 protected、 和 private 關鍵字。如果一個標識符以 (_) 開頭,則該標識符 在庫內是私有的
  • Dart 工具可以指出兩種問題:警告和錯誤。 警告只是說你的代碼可能有問題, 但是並不會阻止你的代碼執行。 錯誤可以是編譯時錯誤也可以是運行時錯誤。遇到編譯時錯誤時,代碼將 無法執行;運行時錯誤將會在運行代碼的時候導致一個異常

基本語法

Dart內置的數據類型

Dart支持的內置類型有numbers、 strings、booleans、lists、maps

  • numbers 數值

num有兩個子類, int 和 double int值: 其取值通常位於 -253 和 253 之間 double : 64-bit (雙精度) 浮點數,符合 IEEE 754 標準

  • strings 字符串

Dart 字符串是 UTF-16 編碼的字符序列。 可以使用單引號、雙引號、三引號來創建字符串

<code>  String string0 = "牛糞糞";
String string1 = '牛轟轟';
String string2 = '''牛轟轟
love
牛糞糞''';
print(string0);
print(string1);
print(string2);
print(string0==string1);
print(string0=="牛糞糞");/<code>
Flutter準備篇之Dart語言初探

注意: 1、== 操作符判斷兩個對象的內容是否一樣。 如果兩個字符串包含一樣的字符編碼序列, 則他們是相等的 2、可以使用 + 操作符來把多個字符串鏈接為一個,也可以把多個 字符串放到一起來實現同樣的功能

num 與string之間相互轉換

<code>  // String 轉 int
var one = int.parse('1');
assert(one == 1);

// String 轉 double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);

// int 轉 String
String oneAsString = 1.toString();
assert(oneAsString == '1');

// double 轉 String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');
/<code>
  • booleans 布爾值

Dart 有一個名字為 bool 的類型,只有兩個對象是布爾類型的:true 和 false 所創建的對象, 這兩個對象也都是編譯時常量。 當 Dart 需要一個布爾值的時候,只有 true 對象才被認為是 true。 所有其他的值都是 flase。

  • lists 集合、列表

編程語言中最常見的集合類型。 在 Dart 中數組就是 List 對象。所以 通常我們都稱之為 lists

Lists 的下標索引從 0 開始,第一個元素的索引是 0,list.length - 1 是最後一個元素的索引。

訪問 list 的長度和元素與 JavaScript 中的用法一樣 list.asMap()可以將list集合轉為map,list角標作為map的key

Set集合和java差不多,特點就是元素對象不重複

<code>  Set set0 = {1, 1, 1, 1, 12, 13, 0};
print(set0);
Set set1 = {12, 13, 0, 3, 4};
print(set1);
print(set1.difference(set0)); //補集
print(set1.union(set0)); //並集
print(set1.intersection(set0)); //交集/<code>
  • maps

Map 是一個鍵值對相關的對象。 鍵和值可以是任何類型的對象。每個 鍵 只出現一次, 而一個值則可以出現多次

關鍵字

標 1 的關鍵字是 內置關鍵字。避免把內置關鍵字當做標識符使用。 也不要把內置關鍵字 用作類名字和類型名字。 有些內置關鍵字是為了方便把 JavaScript 代碼移植到 Dart 而存在的。 例如,如果 JavaScript 代碼中有個變量的名字為 factory, 在移植到 Dart 中的時候,你不必重新命名這個變量。

標 2 的關鍵字,是在 Dart 1.0 發佈以後又新加的,用於 支持異步相關的特性。 你不能在標記為 async 或者 sync 的方法體內 使用 async、 await、或者 yield 作為標識符

Flutter準備篇之Dart語言初探

  • 默認聲明
<code> String str;/<code>

沒有初始化的變量自動獲取一個默認值為null,雖然聲明的時string,但是string類型也是一個對象

  • 賦值聲明
<code>String str  = "牛糞糞";
bool isOK/<code>

bool isOK; //因為默認都屬null,所以不能直接用在if語句中如 if (isOK) { }

運行報錯: Failed assertion: boolean expression must not be null

  • 常量聲明Final and const
<code> final String string0 = "牛糞糞";
const String string1 = "牛轟轟";
/<code>

Final and const 修飾的都是常量

final 修飾的常量是運行時常量,運行時只能賦值一次

const 關鍵字不僅僅只用來定義常量。 可以用來創建不變的值, 還能定義構造函數為 const 類型的,這種類型 的構造函數創建的對象是不可改變的。任何變量都可以有一個不變的值

const 修飾的常量為編譯時常量

<code>final List str0 = ["牛糞糞", "牛轟轟"];
final List str1 = ["牛糞糞", "牛轟轟"];
print(identical(str1, str0)); //輸出false
//說明str0和str1引用指向不同的對象,也就是說內存中有兩份相同的值

const List str2 = ["牛糞糞", "牛轟轟"];
const List str3 = ["牛糞糞", "牛轟轟"];
print(identical(str2, str3)); //輸出true
//說明str2 str3 引用指向同一個內存中的對象/<code>

Dart 是一個真正的面嚮對象語言,方法也是對象並且具有一種 類型, Function。 這意味著,方法可以賦值給變量,也可以當做其他方法的參數。 也可以把 Dart 類的實例當做方法來調用

  • 程序入口main方法
<code>//每個應用都需要有個頂級的 main() 入口方法才能執行
//main() 方法的返回值為 void 並且有個可選的 List<string> 參數
// 這是程序執行的入口
main() {

}

//下面是一個命令行應用的 main() 方法,並且使用了 方法參數作為輸入參數:
void main(List<string> arguments) {
print(arguments);
assert(arguments.length == 2);
assert(int.parse(arguments[0]) == 1);
assert(arguments[1] == 'test');
}/<string>/<string>/<code>
  • 命名參數方法
    方法可以有兩種類型的參數:必需的和可選的。 必需的參數在參數列表前面, 後面是可選參數

(1)可選命名參數
可選參數可以是命名參數或者基於位置的參數,但是這兩種參數不能同時當做可選參數
定義:使用 {param1, param2, …} 的形式來指定命名參數

<code>hello2({int a, int b}) {
print(a);
print(b);
}/<code>

調用:使用這種形式 paramName: value 來指定命名參數

<code>print(hello2(a: 1));
//輸出結果
1
null
null/<code>

(2)可選位置參數
定義:把一些方法的參數放到 [] 中就變成可選位置參數了

<code>hello3(String name, [int age, String str]) {
print(name);
print(age);
print(str);
}/<code>

調用:

<code>//不使用可選參數調用
print(hello3("牛糞糞"));
//使用可選參數調用
print(hello3("牛糞糞", 27, "愛吃豬蹄"));
//使用可選參數調用
print(hello3("牛糞糞", null, "愛吃豬蹄"));/<code>

可選命名比可選位置更加靈活: 命名可以跳過一些參數,但是可選位置只能順序傳參,想要跳過就傳入null

(3)默認參數
定義:在定義方法的時候,可以使用 = 來定義可選參數的默認值。 默認值只能是編譯時常量。 如果沒有提供默認值,則默認值為 null

<code>void hello3(String name, [int age, String str = "123"]) {
print(name);
print(age);
print(str);
}/<code>

還可以使用 list 或者 map 作為默認值

  • 匿名方法
    大部分方法都帶有名字,例如 main() 或者 printElement()。 你有可以創建沒有名字的方法,稱之為 匿名方法,有時候也被稱為 lambda 或者 closure 閉包。 你可以把匿名方法賦值給一個變量, 然後你可以使用這個方法,比如添加到集合或者從集合中刪除。

匿名函數和命名函數看起來類似— 在括號之間可以定義一些參數,參數使用逗號 分割,也可以是可選參數。 後面大括號中的代碼為函數體:

<code>([[Type] param1[, …]]) { 
codeBlock;

};
/<code>

注意:
1、胖箭頭語法
對於只有一個表達式的方法,你可以選擇 使用縮寫語法來定義:

<code>int add(int a, int b) => a + b;
//等價與
int add(int a, int b) { return a+b;}/<code>

在箭頭 (=>) 和冒號 (;) 之間只能使用一個表達式,不能使用語句

2、級聯調用
代碼中的..語法為級聯調用。 使用級聯調用語法, 你可以在一個對象上執行多個操作
3、Dart支持方法中定義方法,並且可以多級嵌套
4、所有的函數都返回一個值。如果沒有指定返回值,則默認把語句 return null; 作為函數的最後一個語句執行

操作符

下表是 Dart 中定義的操作符。 很多操作符都可以重載 在操作符表格中所列的操作符 都是按照優先級順序從左到右,從上到下的方式來列出的, 上面和左邊的操作符優先級要高於下面和右邊的。 例如 % 操作符優先級高於 ==,而 等號 高於 &&

Flutter準備篇之Dart語言初探

可覆寫的操作符
下表中的操作符可以被覆寫。 例如,如果你定義了一個 Vector 類, 你可以定義一個 + 函數來實現兩個向量相加

Flutter準備篇之Dart語言初探

如果你覆寫了 == ,則還應該覆寫對象的 hashCode getter 函數

斷言assert

注意: 在生產模式 assert() 語句被忽略了。在檢查模式 assert(*condition*) 會執行 assert 方法的參數可以為任何返回布爾值的表達式或者方法。 如果返回的值為 true, 斷言執行通過,執行結束。 如果返回值為 false, 斷言執行失敗,會拋出一個異常 AssertionError

流程控制

1、for循環

<code>main() {
List<string> colorList = ['red', 'yellow', 'blue', 'green'];
for (var i = 0; i < colorList.length; i++) {//可以用var或int
print(colorList[i]);
}
}/<string>/<code>

2、while循環

<code>main() {
List<string> colorList = ['red', 'yellow', 'blue', 'green'];
var index = 0;
while (index < colorList.length) {
print(colorList[index++]);
}
}/<string>/<code>

3、do-while循環

<code>main() {
List<string> colorList = ['red', 'yellow', 'blue', 'green'];
var index = 0;
do {
print(colorList[index++]);
} while (index < colorList.length);
}/<string>/<code>

4、break和continue

<code>main() {
List<string> colorList = ['red', 'yellow', 'blue', 'green'];
for (var i = 0; i < colorList.length; i++) {//可以用var或int
if(colorList[i] == 'yellow') {
continue;
}
if(colorList[i] == 'blue') {
break;
}
print(colorList[i]);
}
}/<string>/<code>

5、if-else

<code>void main() {
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
for (var i = 0; i < numbers.length; i++) {
if (numbers[i].isEven) {
print('偶數: ${numbers[i]}');
} else if (numbers[i].isOdd) {
print('奇數: ${numbers[i]}');
} else {
print('非法數字');
}
}
}/<code>

6、三目運算符(? : )

<code>void main() {
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
for (var i = 0; i < numbers.length; i++) {
num targetNumber = numbers[i].isEven ? numbers[i] * 2 : numbers[i] + 4;
print(targetNumber);
}
}/<code>

7、switch-case語句

<code>Color getColor(String colorName) {
Color currentColor = Colors.blue;
switch (colorName) {
case "read":
currentColor = Colors.red;
break;
case "blue":
currentColor = Colors.blue;
break;
case "yellow":
currentColor = Colors.yellow;
break;
}
return currentColor;
}/<code>

異常

dart中的異常捕獲方法和Java,Kotlin類似,使用的也是try-catch-finally; 對特定異常的捕獲使用

on關鍵字. dart中的常見異常有: NoSuchMethodError(當在一個對象上調用一個該對象沒有 實現的函數會拋出該錯誤)、ArgumentError (調用函數的參數不合法會拋出這個錯誤)

<code>main() {
int num = 18;
int result = 0;
try {
result = num ~/ 0;
} catch (e) {//捕獲到IntegerDivisionByZeroException
print(e.toString());
} finally {
print('$result');
}
}

//使用on關鍵字捕獲特定的異常
main() {
int num = 18;
int result = 0;
try {
result = num ~/ 0;
} on IntegerDivisionByZeroException catch (e) {//捕獲特定異常
print(e.toString());
} finally {
print('$result');
}
}/<code>


分享到:


相關文章: