Dart 初探 (一)
前言
Dart 是 Google 為 Flutter 開發的一款用於網頁程式設計的語言,其類似於Javascript,也是一種面向物件的語言,但其採用基於類的程式設計,語法風格接近C語言。
雖說它是開發用於網頁程式設計的,但它也可以開發命令列應用,甚至可以用於開發移動端應用,如 Flutter 就是一款基於 Dart 語言、用於移動端開發的跨平臺開發套件。本篇文章的目的是先簡單瞭解下 Dart 語言基礎,為以後的 Flutter 開發做準備。
開始:建立一個 Dart 專案
使用VS Code,安裝 Dart 擴充套件:
建立 Dart 專案:
-
Ctrl + Shift + P
開啟命令面板,輸入dart
點選 Dart: New Project
,選擇第二項 Console Application
之後選擇一個新專案所在路徑,VS Code 就會自動建立一個示例專案。
點選 main()
方法上方的 Run
按鈕,就可以執行專案程式碼:
可以看到,Dart 專案輸出了結果。
基本語法:變數宣告
變數 var
關鍵字
// var 變數, 可接受任何型別變數,
// 一但賦值型別無法修改——強型別語言,具有型別的概念
var t = "hi world";
print(t);
//t = 1000; 修改會導致編譯失敗
t = "hello world"; //可重新賦值
print(t);
根基類 Object
和 變數 dynamic
關鍵字
-
Object
是 Dart 所有物件的根基類,也就是說在 Dart 中所有類都是Object
的子類(包括Function
和Null
) -
dynamic
宣告的物件編譯器會提供所有可能的組合,因此編譯時可能不會報錯,但在執行時可能會產生報錯——執行時錯誤 -
Object
宣告的物件只能使用Object
的屬性與方法,否則編譯器會報錯// dynamic 變數 // 與var 不同, 賦值後型別可以修改 dynamic tt; tt = "cool guy"; print(tt); tt = "cool boy"; //可重新賦值 print(tt); tt = 10086; //也可賦值為其他型別 print(tt); //提供可能的內部方法的組合,編譯時不會報錯, //但物件的屬性或方法不存在時執行時會報錯 print(tt.length); // Object 類 // 所有 物件的根基類, 任何型別均可賦值給Object物件 Object o = "ohhhhh!"; print(o); o = 5201314; //可重新賦值,可賦值為其他型別值 print(o); //print(o.length); //只能使用Object物件的方法,否則編譯器會報錯
變數 final
和 const
關鍵字
如果打算宣告一個不改變的變數值,使用final
或 const
-
const
變數是一個編譯時常量(編譯時直接替換為常量值) -
final
變數在第一次使用時被初始化
// final 變數
final str = "This is a final str";
// 在第一次使用時被初始化
print(str);
// str = "This is an another final str"; 重新賦值編譯器會報錯
// const 編譯時常量
// 編譯時被替換為常量值
const str2 = "This is a const str";
print(str2);
//str2 = "This is an another const str"; 重新賦值編譯器會報錯
空安全
- 不可空型別使用前必須初始化,可空型別使用前必須判空
- 預期變數不能為空,但在定義時不能確定其初始值,則可以加上
late
關鍵字,表示會稍後初始化,但是在正式使用它之前必須得保證初始化過了,否則會報錯 - 可空型別的變數,在某些情況下即使我們給它賦值過了,但是前處理器仍然有可能識別不出,這時我們就要顯式(通過在變數後面加一個”!“符號)指定其不為
null
- 可空型別的函式變數,使用
?.call()
進行呼叫,表示不為空時呼叫函式
// 空安全
int a; //預設為不可空型別,必須在使用前初始化
//print(a * 7); // 在初始化前使用時, 編譯器會報錯
int? b; // 可空型別
if (b != null) {
print(b * 7); // 可空型別在使用時, 必須先判空
}
// late 關鍵字, 延遲初始化
late int k;
k=9;
// 使用! 顯示指定不為null
var s = k! * 9;
// 函式變數使用?.call() 非空時呼叫
fun?.call()
進階語法:函式
函數語言程式設計
Dart 作為一種真正的面向物件的語言,即使函式也是物件,且屬於一個型別Function
,這說明函式可以賦值給變數或者作為引數傳遞給其他函式,這正是函數語言程式設計的典型特徵。
函式宣告
- 不顯式宣告返回值型別,會預設當作
dymastic
處理,沒有型別推斷
int sum(int a, int b) {
return a + b;
}
// 不宣告返回值型別, 當作 dymastic 處理, 不是推斷得到的型別
sum2(int a, int b) {
return a + b;
}
// 單表示式函式
bool isTrue (bool result) => !result;
函式引數
-
可選的位置引數:使用
[]
對可空型別引數進行包裝, 需放置在引數列表的最後面// 函式引數 String see(String from, String msg, [String? states]) { var result = '$from see $msg'; if (states != null) { result = '$result in $states'; } return result; } print(see('I', 'you')); // 不帶可選引數呼叫 print(see('I', 'you', 'a football game')); // 帶可選引數呼叫
-
可選的命名引數:使用
{}
對可空型別引數進行包裝, 需放置在列表引數的最後面。Flutter中常用。void setFlags({bool? isFromOuter, bool? isShow}) { // 處理邏輯... } setFlags(isFromOuter: false, isShow: true); // 帶可選引數呼叫
說明:不能同時使用可選的位置引數和可選的命名引數;可選引數列表需為可空型別,否則編譯會報錯
函式作為變數
// 函式作為變數
var say = (str) {
print(str);
};
say("hello");
函式作為型別引數
// 函式作為函式引數
void execute(var callback) {
callback();
}
execute(() => print("callback!"));