從上兩篇文章中我們對Flutter已經(jīng)有一個大概的了解,接下來我們從Dart 語法來進一步了解Flutter,我們從以下幾個部分來入手:
- 1.Dart中的變量與常量
- 2.Dart中的數(shù)據(jù)類型
- 3.Dart中的運算符
- 4.Dart中的方法
1.Dart中的變量常量
1.1 var變量
//變量聲明初始化
void varibleFunc() {
var name;
print(name);
name = 'MG';
print(name);
name = 1;
print(name);
var age = 18;
print(age);
}
打印結(jié)果
flutter: null
flutter: MG
flutter: 1
flutter: 18
說明:
- 使用
var聲明一個變量,可以賦值不同的類型 -
var聲明的變量如果沒有初始化,那么它的值為nil
1.2final 最終變量
//最終變量聲明初始化
void finalVariableFunc() {
final name;
print(name);
name = 'MG';
print(name);
name = 'xm';
print(name);
}
此時編譯器會報錯
- 使用final聲明的一個只能賦值一次的變量
- 使用final聲明的變量在使用之前必須賦值
- 它是最終變量
1.3const常量
//常量聲明初始化
void constanFunc() {
const name = 'LH';
print(name);
//這里再次賦值,編譯器會報錯
//name = "MG";
//print(name);
}
- 使用const聲明的常量在聲明時就得賦值
- 使用const聲明的常量賦值后不能修改
如果您從未打算更改變量,可以使用
final或const來代替var或添加到類型之外。final變量只能設(shè)置一次;const變量 是編譯時常量。(Const變量 隱式為final。)最終的頂級變量或類變量在第一次使用時進行初始化。
2.Dart中的數(shù)據(jù)類型
Dart 語言對以下類型有特殊的支持:
- numbers
- strings
- booleans
- lists
- sets
- maps
- runes
- symbols
可以使用字面量 初始化這些特殊類型中的任何一個對象。例如,this is a string 是一個字符串字面量,而 true 是一個布爾字面量。
因為 Dart 中的每個變量都指向一個對象(類的實例),所以通??梢允褂脴?gòu)造函數(shù)來初始化變量。一些內(nèi)置類型有自己的構(gòu)造函數(shù)。例如,您可以使用 Map() 構(gòu)造函數(shù)來創(chuàng)建映射
2.1num類型
Dart中num有兩種,int 和double
//num類型
void numFunc() {
num i = 2;
print(i);
i = 1.1; //用num聲明的變量這里是可以轉(zhuǎn)換類型的
print(i);
int a = 1;
print(a.isEven); //是否偶數(shù)
print(a.isOdd); //是否奇數(shù)
double b = 1.12;
print(b);
// String -> int
int one = int.parse('1');
print(one + 2); // 輸出3
// String -> double
var onePointOne = double.parse('1.1');
print(onePointOne + 2); // 輸出3.1
// int -> String
String oneAsString = 1.toString();
// The argument type 'int' can't be assigned to the parameter type 'String'
//print(oneAsString + 2);
// 輸出 1 + 2
print('$oneAsString + 2');
// 輸出 1 2
print('$oneAsString 2');
// double -> String 注意括號中要有小數(shù)點位數(shù),否則報錯
String piAsString = 3.14159.toStringAsFixed(2);
print(piAsString); // 截取兩位小數(shù), 輸出3.14
String aString = 1.12618.toStringAsFixed(2);
// 檢查是否四舍五入,輸出1.13,發(fā)現(xiàn)會做四舍五入
print(aString);
}
- num 變量,在使用之前必須賦值
- num支持運算符
+,-,*,/,%(取模),~/(取整) - num類型的數(shù)據(jù)也能轉(zhuǎn)換類型
toInt(),toDouble(),toString()
2.2Strings類型
// 關(guān)于string 類型測試
void stringFunc() {
// `Dart字符串` 是由UTF-16編碼單元組成的序列。可以使用`單引號`或`雙引號`創(chuàng)建字符串:
var s1 = 'hello';
var s2 = "flutter";
var s3 = '我是MG';
var s4 = 'MG';
print(s1 + s2); //輸出helloflutter
print(s3*2); //我是MG我是MG
// 可以使用相鄰的字符串字直接連接在一起 或者 `+操作符` 來連接字符串:
var s5 = 'Flutter_''MG_'"hello";
assert(s5 ==
'Flutter_MG_hello');
// 另一種創(chuàng)建多行字符串的方法是:`使用帶有單引號` 或 `雙引號的三引號:`
var s7 = '''
單引號創(chuàng)建多行字符串
注意要各行哦''';
var s8 = """雙引號創(chuàng)建多行字符串
注意要各行哦""";
print(s7);
print(s8);
// 單引號或者雙引號里面嵌套使用引號。
// 用 {} 來計算字符串中變量的值,需要注意的是如果是表達式需要${表達式}
// 單引號嵌套雙引號
String s9 = '$s1 a "MG" ${s3}';
// 輸出 hello a "MG" 我是MG
print(s9);
// 雙引號嵌套單引號
String s10 = "${s4.toUpperCase()} abc 'MG' $s4.toUpperCase()";
// 輸出 MG abc 'aaa' MG.toUpperCase(),
// 可以看出 '$s4.toUpperCase()' 沒有加'{}',導(dǎo)致輸出結(jié)果是'MG.toUpperCase()'
print(s10);
String s11 = '這是第一行\(zhòng)n這是第二行';
String s12 = r'這是第一行\(zhòng)n這是第二行';
/*輸出
* 這是第一行
* 這是第二行
*/
print(s11);
print(s12); //輸出 這是第一行\(zhòng)n這是第二行
print(s12[1]); //輸出 是
}
-
Dart字符串是由UTF-16編碼單元組成的序列??梢允褂?code>單引號或雙引號創(chuàng)建字符串: - 創(chuàng)建多行字符串的方法是:
使用帶有單引號或雙引號的三引號: - 用
{}來計算字符串中變量的值,需要注意的是如果是表達式需要${表達式} -
Dart中字符串的操作是很方便的,可以使用角標的方式獲取字符串某個位置上的字符 - 字符串之間也可以進行
+,*運算 - 在字符串中如果不需要轉(zhuǎn)義那么在字符串前添加
r
2.3Bool 類型
為了表示布爾值,Dart有一個名為 bool 的類型。只有兩個對象具有 bool類型 : 布爾字面值 true 和 false,它們都是編譯時常量。因為和我們一般了解一致 這里不做贅述
2.4list類型
//關(guān)于list
void listsFunc() {
//聲明一個可變list
var list1 = [1,2,3];
//聲明一個不可變list
var list2 = const [1,2,3];
//list2[1] = 4; // 報錯
//在list中可以存放不同類型的數(shù)據(jù)
var list3 = [1, 'name', list2];
print(list3);
// spread operator (...) 的用法
var list4 = [0, ...list1];
print(list4); // [0, 1, 2, 3]
// 注意插入空的情況 那么就需要 `(...?)`
var list5 ;
var list6 = [0, ...?list5];
print(list6); // [0]
// list 增刪改查
// 增加元素
list1.add(4);
print(list1); // [1, 2, 3, 4]
// 刪除元素
list1.remove(4);
print(list1); // [1, 2, 3]
// 修改元素
list1[1] = 100;
print(list1); // [1, 100, 3]
// 查詢
print(list1.indexOf(3)); // 2 獲取元素的下標
print(list1.elementAt(1)); // 100
print(list1.contains(666)); // false
}
2.5Map類型
map 是一個關(guān)聯(lián)鍵和值的對象 (也就是我們所說的字典)
-
map中的鍵值對是唯一的 -
map里面的value可以相同 -
map里面的value可以為空字符串
//關(guān)于maps
void mapsFunc(){
//可變map
var person = {
// Key: Value
'age': 18,
'name': 'LiHua',
'hobby': '女',
'height': 1.85
};
//不可變map
// var student = const {'name', 'zhangsan'};
print(person); // {age: 18, name: LiHua, hobby: 女, height: 1.85}
print('${person.keys},${person.values}'); // (age, name, hobby, height),(18, LiHua, 女, 1.85)
// Map的賦值,中括號中是Key,這里可不是數(shù)組
person['age'] = '20';
//Map中的鍵值對是唯一的
//同Set不同,第二次輸入的Key如果存在,Value會覆蓋之前的數(shù)據(jù)
person['name'] = 'xiaoming';
// map里面的value可以相同
person['hobby'] = 'male';
// map里面value可以為空字符串
person['hobby'] = '';
print(person); // {age: 20, name: xiaoming, hobby: , height: 1.85}
}
3.Dart中的運算符
Dart中有兩種特殊的運算符,??=, ??;
//運算符
void operatorFunc() {
//Dart中有兩種特殊的運算符
//賦值運算 ??=
//條件表達式 ??
var a;
a ??= 10; //如果a為null時則賦值
a ??= 5; //如果a不為null時則不賦值
print(a); //輸出 10
var b;
b = 5;
print(b ?? a); //輸出5
var c;
print(c ?? a); //輸出10
// ??如果左邊有值返回左邊,如果左邊沒有值則返回右邊
}
4.Dart中的方法
-
Dart中的方法也是一個對象 -
Dart方法的返回值和參數(shù)類型可以省略 -
Dart方法的執(zhí)行語句只有一句的時候,可以使用箭頭函數(shù)=>
4.1=>箭頭函數(shù)
//Dart的方法
void functionDemo() {
print(sum(10, 20));
}
// int sum(int a, int b) {
// return a + b;
// }
//也可以寫成這樣,不過不建議這樣寫
// sum(a, b) => a + b;
//同時 =>函數(shù)也可以加入三目運算
sum(a, b) => a == 20 ? a + b : a - b;
4.2Dart方法的可選參數(shù)
-
Dart方法中有可選參數(shù)并用{}時,傳遞參數(shù)的時候必須帶上形參的名字 -
Dart方法中有可選參數(shù)并用[]時,傳遞參數(shù)的時候參數(shù)的位置時固定的
//Dart的方法
void functionDemo() {
//必須帶上行參的名字(c,b)順序隨意
print(sum1(10, c: 1, b: 5));
//b:1 c:5
print(sum2(10, 1, 5));
}
//sum1(int a, {b, c}) {
//如果需要指定可選參數(shù)的類型,可以加上?告訴編譯器,后面處理了為空的情況
//sum1(int a, {int? b, int? c}) {
//也可以給可選參數(shù)賦默認值
sum1(int a, {int b = 1, int c = 2}) {
b ??= 0;
c ??= 0;
return a - b + c;
}
//給可選參數(shù)設(shè)定位置,在傳參時b和c的位置不能變
sum2(int a, [int b = 1, int c = 2]) {
return a - b + c;
}
4.3Dart方法做為參數(shù)傳遞
前文中我們提到過Dart方法是一個對象,那么方法也能作為一個參數(shù)傳遞
void functionDemo() {
var list = [1,2,3,4];
//print這個方法作為一個參數(shù)傳入
forEachFunc(list, print); //輸出1,2,3,4
}
forEachFunc(List list, void func(var element)) {
//在for循環(huán)內(nèi)部調(diào)用外部傳入的方法
for (var e in list) func(e);
}
4.4Dart中的匿名函數(shù)
匿名方法顧名思義,就是沒有方法名稱的方法
void functionDemo() {
var list = [1,2,3,4];
//匿名函數(shù)作為參數(shù)
forEachFunc(list, (var e) {
e ++;
print(e);
}); //輸出1,2,3,4
var func = () {
print('我是一個匿名方法');
};
func();
}
forEachFunc(List list, void func(var element)) {
for (var e in list) func(e);
}
4.5Dart中的閉包closure
- 閉包:定義在函數(shù)里面的函數(shù)就是閉包,閉包也是一個對象
- 閉包的作用:它可以訪問外部函數(shù)的局部變量
我們通過下面的示例來理解
//Dart中的閉包
void closureDemo() {
var func = funcA();
func();
func();
func();
func();
//輸出1,2,3,4
//funA里的count參數(shù)一直被持有
var func1 = funcA();
func1();
func1();
func1();
func1();
//輸出 1,2,3,4
}
funcA() {
int count = 0;
return ()=>print(count++); //這個匿名函數(shù)就是一個閉包
}
最后
大家也可以對照Dart官方文檔一起學(xué)習(xí)