摘要:中所有的基礎(chǔ)類(lèi)型類(lèi)等都繼承,默認(rèn)值是,自帶和,而如果是或者的話,那么它只有一個(gè)方法。斷言失敗則程序立刻終止檢查是否為空字符串檢查是否小于等于檢查是否為檢查是否為字符串中,支持類(lèi)型。類(lèi)繼承類(lèi),通過(guò)關(guān)鍵字調(diào)用類(lèi)的構(gòu)造函數(shù)。泛型全面支持泛型。
目錄介紹
01.變量聲明
1.1 var聲明變量
1.2 變量和常量
1.3 dynamic和Object
02.數(shù)據(jù)類(lèi)型
2.1 基本數(shù)據(jù)類(lèi)型
2.2 String字符串
2.3 List數(shù)組
2.4 Map集合
03.Dart函數(shù)和運(yùn)算符
3.1 Dart函數(shù)介紹
3.2 命名參數(shù)
3.3 參數(shù)默認(rèn)值
3.4 void無(wú)返回值
3.5 匿名函數(shù)
3.6 運(yùn)算符介紹
04.Dart流程控制
4.1 流程控制語(yǔ)句
4.2 if和else
4.3 for循環(huán)
4.4 while循環(huán)
4.5 break和continue
4.6 switch和case
4.7 assert斷言
05.Dart面向?qū)ο?/p>
5.1 類(lèi)簡(jiǎn)單介紹
5.2 構(gòu)造函數(shù)
5.3 繼承類(lèi)
5.4 重載和重寫(xiě)
5.5 抽象類(lèi)
5.6 訪問(wèn)權(quán)限
5.7 靜態(tài)方法
5.8 泛型
06.Dart異步解讀
6.1 Future簡(jiǎn)單介紹
6.1.1 普通異步案例
6.1.2 耗時(shí)異步案例
6.2 async/await介紹
6.3 看一個(gè)案例
07.Dart異常捕獲
7.1 異常處理形式
7.2 拋出異常
7.3 捕獲異常
7.4 Finally講解
08.Dart枚舉
8.1 枚舉使用
8.2 元數(shù)據(jù)
8.3 自定義注解
09.Dart字符串
9.1 String簡(jiǎn)單介紹
9.2 單雙引號(hào)互相嵌套
9.3 字符串拼接方式
想換個(gè)工作,渴望同行內(nèi)推我
個(gè)人信息
姓名:楊充【26歲】
郵箱:yangchong211@163.com
微信:13667225184
GitHub:https://github.com/yangchong211
博客匯總:https://github.com/yangchong2...
干活集中營(yíng):Android端技術(shù)博客和開(kāi)源項(xiàng)目審核員
目前工作情況:在職狀態(tài)
技術(shù)項(xiàng)目和博客:GitHub項(xiàng)目7k以上star,follower1.1k以上,發(fā)表博客100多篇。
熱愛(ài)技術(shù):開(kāi)源項(xiàng)目和博客多次被鴻洋,郭霖,Android技術(shù)周刊,干活集中營(yíng)等等推薦。
學(xué)歷:武漢軟件工程職業(yè)學(xué)院,大專(zhuān)學(xué)歷
工作年限:3年多
工作地點(diǎn):北京
關(guān)于近期投遞簡(jiǎn)歷一點(diǎn)感想
從進(jìn)入Android這個(gè)行業(yè)以來(lái),前兩次幾乎都是朋友內(nèi)推,面試機(jī)會(huì)相對(duì)容易,都是一個(gè)App一個(gè)人做或者兩個(gè)人做,用戶(hù)相對(duì)來(lái)說(shuō)并不多。這次想著離職,主要是想進(jìn)入一個(gè)較大的平臺(tái),大概可以理解為Android端有個(gè)至少四五人,可以進(jìn)行技術(shù)交流,渴望自己能夠在技術(shù)上突破,這就像自己平時(shí)獨(dú)自跑步,和跟著一群跑馬拉松的人跑步,那種緊張感肯定是不一樣的。
近段時(shí)間,嘗試著向一些較大的公司投遞簡(jiǎn)歷,大概在拉鉤上投了15個(gè)左右(不喜歡海投),發(fā)現(xiàn)絕大多數(shù)簡(jiǎn)歷到不了技術(shù)那里,就被人事說(shuō)學(xué)歷不夠,經(jīng)驗(yàn)不夠,工作不匹配等情況回絕。不過(guò)也可以理解,看簡(jiǎn)歷無(wú)非就是學(xué)歷和經(jīng)驗(yàn),貌似自己的履歷是差了一點(diǎn)。
這大概是第一次在網(wǎng)上發(fā)一個(gè)主動(dòng)希望同行內(nèi)推的介紹,如果你的公司有Android方面的招聘,能否內(nèi)推一下我這個(gè)小人物,感謝。
01.變量聲明 1.1 var聲明變量
類(lèi)似于kotlin中的var,它可以接收任何類(lèi)型的變量,但最大的不同是Dart中var變量一旦賦值,類(lèi)型便會(huì)確定,則不能再改變其類(lèi)型,如:
var t; t="yc"; // 下面代碼在dart中會(huì)報(bào)錯(cuò),因?yàn)樽兞縯的類(lèi)型已經(jīng)確定為String, // 類(lèi)型一旦確定后則不能再更改其類(lèi)型。 t=1000;
最大的不同是Dart中var變量一旦賦值,類(lèi)型便會(huì)確定,則不能再改變其類(lèi)型。因?yàn)镈art本身是一個(gè)強(qiáng)類(lèi)型語(yǔ)言,任何變量都是有確定類(lèi)型的,在Dart中,當(dāng)用var聲明一個(gè)變量后,Dart在編譯時(shí)會(huì)根據(jù)第一次賦值數(shù)據(jù)的類(lèi)型來(lái)推斷其類(lèi)型,編譯結(jié)束后其類(lèi)型就已經(jīng)被確定。
思考一下,dart在編譯時(shí)是如何確定數(shù)據(jù)的類(lèi)型呢?
1.2 變量和常量
變量如下所示
var curPage = 0; var title = "瀟湘劍雨:小楊逗比";
Dart 不需要給變量設(shè)置 setter getter 方法, 這和 kotlin 等類(lèi)似。Dart 中所有的基礎(chǔ)類(lèi)型、類(lèi)等都繼承 Object ,默認(rèn)值是 NULL, 自帶 getter 和 setter ,而如果是 final 或者 const 的話,那么它只有一個(gè) getter 方法。
const 的值在編譯期確定,final 的值要到編譯時(shí)才確定。
Dart 中 final 表示常量
//final 表示常量 final title = "瀟湘劍雨:小楊逗比";
static const 組合代表了靜態(tài)常量
//static const 組合代表了靜態(tài)常量 static const String complete = "COMPLETE";
final和const區(qū)別
兩者區(qū)別在于:const 變量是一個(gè)編譯時(shí)常量,final變量在第一次使用時(shí)被初始化。被final或者const修飾的變量,并且變量類(lèi)型可以省略。
注意點(diǎn)
const變量同時(shí)也是final變量,實(shí)例變量可以為final但不能是const。
編譯錯(cuò)報(bào)錯(cuò),原因final變量只能賦值一次!
//定義初始化一個(gè)變量 final double number = 13.14; number = 520; //調(diào)用打印數(shù)字方法 printNumber(number);
在Java中可以直接通過(guò) + 號(hào)將字符串和int類(lèi)型拼接,但是在Dart中是不行的。
//在Java中,下面操作可行 ToastUtils.showRoundRectToast("二維碼掃描"+1000); //在dart中,下面錯(cuò)誤操作,編譯不通過(guò),直接會(huì)有紅色提示 int yc = 0; print("瀟湘劍雨" + yc); //在dart中,下面正確操作 int yc = 0; print("瀟湘劍雨" + yc.toString());1.3 dynamic和Object
Object 是dart所有對(duì)象的根基類(lèi),也就是說(shuō)所有類(lèi)型都是Object的子類(lèi)(包括Function和Null),所以任何類(lèi)型的數(shù)據(jù)都可以賦值給Object聲明的對(duì)象.
dynamic與var一樣都是關(guān)鍵詞,聲明的變量可以賦值任意對(duì)象.而dynamic與Object相同之處在于,他們聲明的變量可以在后期改變賦值類(lèi)型.
dynamic t; Object x; t = "hi world"; x = "Hello Object"; //下面代碼沒(méi)有問(wèn)題 t = 1000; x = 1000;
dynamic與Object不同的是,dynamic聲明的對(duì)象編譯器會(huì)提供所有可能的組合,而Object聲明的對(duì)象只能使用Object的屬性與方法, 否則編譯器會(huì)報(bào)錯(cuò). 如:
dynamic a; Object b; main() { a = ""; b = ""; printLengths(); } printLengths() { // no warning print(a.length); // warning: // The getter "length" is not defined for the class "Object" print(b.length); }
變量a不會(huì)報(bào)錯(cuò), 變量b編譯器會(huì)報(bào)錯(cuò)
dynamic的這個(gè)特性與Objective-C中的id作用很像.
dynamic的這個(gè)特點(diǎn)使得我們?cè)谑褂盟切枰裢庾⒁?這很容易引入一個(gè)運(yùn)行時(shí)錯(cuò)誤.
02.數(shù)據(jù)類(lèi)型 2.1 基本數(shù)據(jù)類(lèi)型
var 可以定義變量,同時(shí) Dart 屬于動(dòng)態(tài)類(lèi)型語(yǔ)言,支持閉包。
Dart 中 number 類(lèi)型分為 int 和 double ,其中 java 中的 long 對(duì)應(yīng)的也是 Dart 中的 int 類(lèi)型。Dart 中沒(méi)有 float 類(lèi)型。
//int類(lèi)型 這里沒(méi)有l(wèi)ong類(lèi)型 var positionIndex = 0; //double類(lèi)型 這里沒(méi)有float類(lèi)型 var time = 1993.03;
這里提個(gè)小建議,聲明變量的時(shí)候,可以選擇加上具體類(lèi)型。添加類(lèi)型可以更加清晰表達(dá)你的意圖。
//定義初始化一個(gè)變量 double number = 13.14;
Dart 下只有 bool 型可以用于 if 等判斷,不同于 JS 這種使用方式是不合法的 var g = "null"; if(g){} 。
以bool代表布爾值,只有兩個(gè)對(duì)象是布爾類(lèi)型的,那就是true和false所創(chuàng)建的對(duì)象,這兩個(gè)對(duì)象都是編譯時(shí)常量。
//類(lèi)似Java中的布爾類(lèi)型 bool mIsLogin = false; if (!mIsLogin) { //沒(méi)有登陸 print("沒(méi)有登陸"); } else { //已經(jīng)登陸 Navigator.of(context).push(new MaterialPageRoute(builder: (context) { return new CollectPage(); })); }
注意,下面這種情況會(huì)報(bào)錯(cuò)
String name ="yc"; //報(bào)錯(cuò) 因?yàn)閚ame不是bool類(lèi)型 if(name){ print(name); }
可以使用的是先式的檢查值。assert是語(yǔ)言?xún)?nèi)置的斷言的函數(shù),僅在檢查模式有效,在開(kāi)發(fā)過(guò)程中,除非條件為真,否則會(huì)引發(fā)異常。(斷言失敗則程序立刻終止)
// 檢查是否為空字符串 var fullName = "doubi"; assert(fullName.isEmpty); // 檢查是否小于等于0 var hitPoints = 0; assert(hitPoints <= 0); // 檢查是否為 null. var unicorn; assert(unicorn == null); // 檢查是否為 NaN. var iMeantToDoThis = 0 / 0; assert(iMeantToDoThis.isNaN);2.2 String字符串
Dart 中,switch 支持 String 類(lèi)型。后面會(huì)多帶帶拿出來(lái)講解一下。
//字符串 var title = "瀟湘劍雨:小楊逗比";2.3 List數(shù)組
聲明一個(gè)list非常的簡(jiǎn)單,可以簡(jiǎn)單使用方括號(hào)[]定義list。下面是list的常用操作。
main(Listargs) { //或者 List arr1 = [1,2,3,4]; var arr2 = [1,2,3,4]; print(list); //Output: [1, 2, 3, 4] //Length 長(zhǎng)度 print(list.length); //Selecting single value 獲取單個(gè)值 print(list[1]); //Outout: 2 //Adding a value 添加值到list list.add(10); //Removing a single isntance of value 刪除單個(gè)值 list.remove(3); //Remove at a particular position 刪除指定位置的值 list.removeAt(0); }
注意:第一個(gè)元素索引是0,最后一個(gè)元素是length-1
如果你想定義一個(gè)編譯時(shí)常量list,例如,list的內(nèi)容是不可改變的,可以使用關(guān)鍵字const
var list = const [1,2,3,4];2.4 Map集合
定義map也很簡(jiǎn)單。可以使用花括號(hào){}定義map。
void test() { var map = { "key1": "value1", "key2": "value2", "key3": "value3" }; //Fetching the values 獲取值 print(map["key1"]); //Output: value1 print(map["test"]); //Output: null //Add a new value 添加值 map["key4"] = "value4"; //Length 獲取長(zhǎng)度 print(map.length); //Check if a key is present 檢查是否存在 var containsKey = map.containsKey("value1"); print(containsKey); var entries = map.entries; var values = map.values; }
打印日志
2019-06-20 17:22:39.200 4281-4329/com.hwmc.auth I/flutter: value1 2019-06-20 17:22:39.200 4281-4329/com.hwmc.auth I/flutter: null 2019-06-20 17:22:39.200 4281-4329/com.hwmc.auth I/flutter: 4 2019-06-20 17:22:39.200 4281-4329/com.hwmc.auth I/flutter: false
也可以使用map構(gòu)造函數(shù)定義map。
可以發(fā)現(xiàn)map可以存儲(chǔ)多種類(lèi)型的數(shù)據(jù)
var squares = new Map(); squares["a"] = 1; squares["b"] = 2; squares["c"] = 3.0; squares["d"] = [1,2]; squares["e"] = "yc逗比"; print(squares["a"]); print(squares["e"]);
打印日志
2019-06-20 17:27:32.841 4281-4329/com.hwmc.auth I/flutter: 1 2019-06-20 17:27:32.841 4281-4329/com.hwmc.auth I/flutter: yc逗比03.Dart函數(shù)和運(yùn)算符 3.1 Dart函數(shù)介紹
dart中的函數(shù)和JavaScript中有點(diǎn)類(lèi)似。你需要定義就是函數(shù)的名字、返回值(有返回值或者void)、參數(shù)。
void test(){ var name = fullName("楊充", "逗比"); print(name); } String fullName(String firstName, String lastName) { return "$firstName $lastName"; }3.2 命名參數(shù)
dart有個(gè)叫命名參數(shù)的東西。當(dāng)你調(diào)用函數(shù)的時(shí)候,你必須指定參數(shù)的名字。要使用命名參數(shù),可以將函數(shù)的參數(shù)包括在花括號(hào){}內(nèi)。
如果你在調(diào)用命名參數(shù)的函數(shù)時(shí),沒(méi)有指定參數(shù)的名字,則會(huì)提示紅色報(bào)錯(cuò),無(wú)法通過(guò)編譯。
void test(){ var name = fullName("楊充", "逗比"); print(name); } String fullName(String firstName, String lastName) { return "$firstName $lastName"; }3.3 參數(shù)默認(rèn)值
你可以給函數(shù)的命名參數(shù)一個(gè)默認(rèn)值。下面的例子給lastName一個(gè)默認(rèn)值。
void test(){ var name = fullName("楊充", "逗比"); print(name); } fullName(String firstName, String lastName) { return "$firstName $lastName"; }3.4 void無(wú)返回值
大多數(shù)都是void無(wú)返回值的函數(shù),這個(gè)跟java中類(lèi)似。沒(méi)什么好講的……
3.5 匿名函數(shù)
在dart中函數(shù)比較靈活,例如,你可以將函數(shù)當(dāng)參數(shù)傳遞給另一個(gè)函數(shù)。
void test(){ out(printOutLoud); } out(void inner(String message)) { inner("Message from inner function"); } printOutLoud(String message) { print(message.toUpperCase()); }
這里定義一個(gè)函數(shù)名字為out,需要一個(gè)函數(shù)參數(shù)。然后我定義一個(gè)名為printOutLoud的函數(shù),他所做的就是將字符串以大寫(xiě)的形式打印。
dart 也有匿名函數(shù),所以上面的例子中不用預(yù)定一個(gè)函數(shù),而是傳遞一個(gè)匿名函數(shù)。
另一個(gè)匿名函數(shù)的例子。
3.6 運(yùn)算符介紹這部分和java差不多,可以直接看我java部分的博客:運(yùn)算符
04.Dart流程控制 4.1 Dart流程控制
大概有這么多
if和else
for循環(huán)
while循環(huán)
break和continue
switch和case
assert斷言
4.2 if和else
if-else 和其他語(yǔ)言一樣比較簡(jiǎn)單。
var number = 57; if (number > 100) { print("Large Number"); } else if (number < 100) { print("Small Number"); } else { print("Number is 100"); }
可以用三元運(yùn)算符代替if-else
int age = 60; String status = age < 50 ? "年輕人" : "老年人";4.3 for循環(huán)
for循環(huán)和java幾乎是一樣的,代碼如下
void test() { for (int i = 0; i < 10; i++) { print("$i"); } }4.4 while循環(huán)
while循環(huán)如下所示
void test() { int i = 0; while(i < 10) { print("$i"); i++; } }
The classic for do while loop. 典型的do while循環(huán)。
void test() { int i = 0; do { print("$i"); i++; } while (i < 10); }4.6 break和continue 4.7 switch和case
代碼如下所示
void test() { int age = 50; switch(age) { case 10: print("Too Young."); break; case 20: case 30: print("Still Young!"); break; case 40: print("Getting old."); break; case 50: print("You are old!"); break; } }05.Dart面向?qū)ο?/b> 5.1 類(lèi)簡(jiǎn)單介紹
創(chuàng)建一個(gè)類(lèi)和創(chuàng)建類(lèi)的實(shí)例
void test1(){ Dog d = new Dog(); } class Dog { } var cat = new Cat("逗比", 12); class Cat { String name; int age; Cat(String name, int age) { this.name = name; this.age = age; } }5.2 構(gòu)造函數(shù)
普通構(gòu)造函數(shù)
var cat = new Cat("逗比", 12); class Cat { String name; int age; Cat(String name, int age) { this.name = name; this.age = age; } }
命名構(gòu)造函數(shù)
給構(gòu)造函數(shù)提供了名稱(chēng),這樣做使得不同的構(gòu)造函數(shù)變的更加清晰。
Map map = new Map(); map["name"]= "哈巴狗"; map["age"] = 5; Dog d = new Dog.newBorn(map); class Dog { String name; int age; Dog(this.name, this.age); Dog.newBorn(Map json) { name = json["name"]; age = json["age"]; } }5.3 繼承類(lèi)
可以使用extends關(guān)鍵字繼承其他的類(lèi)。
Pug 類(lèi)繼承Dog類(lèi),通過(guò)super關(guān)鍵字調(diào)用Dog類(lèi)的構(gòu)造函數(shù)。
Pug p = new Pug("逗比哈巴狗", 5); print(p.name); class Dog { String name; int age; Dog(this.name, this.age); Dog.newBorn() { name = "Doggy"; age = 0; } } class Pug extends Dog { Pug(String name, int age): super(name, age); }
也可以通過(guò)this關(guān)鍵字,在冒號(hào)之后調(diào)用同一個(gè)類(lèi)中的其他構(gòu)造函數(shù)。
定義了兩個(gè)命名構(gòu)造函數(shù),他們只需要dog的名字,然后調(diào)用Pug的默認(rèn)構(gòu)造函數(shù)。
Pug p = new Pug.small("傻逼"); print(p.name); class Dog { String name; int age; Dog(this.name, this.age); Dog.newBorn() { name = "逗比哈巴狗"; age = 0; } } class Pug extends Dog { Pug(String name, int age): super(name, age); Pug.small(String name): this(name, 1); Pug.large(String name): this(name, 3); }5.4 重載和重寫(xiě)
方法重寫(xiě)
代碼如下,最后打印值是:你真是個(gè)逗比
Pug p = new Pug(); print(p.bark()); class Dog { bark() { print("Bow Wow"); } } class Pug extends Dog { @override bark() { print("你真是個(gè)逗比!"); } }
方法重載
5.5 抽象類(lèi)
可以通過(guò)abstract關(guān)鍵字聲明抽象類(lèi)
只需要在類(lèi)聲明前添加abstract關(guān)鍵字,方法不需要。方法只需要簽名,不需要實(shí)現(xiàn)。
abstract class AbstractDog { void eat(); void _hiddenMethod(); } class SmallDog extends AbstractDog{ @override void _hiddenMethod() { } @override void eat() { } }5.6 訪問(wèn)權(quán)限
默認(rèn)類(lèi)中的所有屬性和方法是public的。在dart中,可以在屬性和方法名前添加“_”使私有化。現(xiàn)在讓我們使name屬性私有化。
可以發(fā)現(xiàn),調(diào)用私有化變量或者方法的時(shí)候會(huì)出現(xiàn)紅色警告
void test() { Dog d = new Dog("哈巴狗", 5); //這個(gè)報(bào)錯(cuò) print(d.name); print(d.age); }
Dog代碼如下所示
class Dog { String _name; int age; Dog(this._name, this.age); String get respectedName { return "Mr.$_name"; } set respectedName(String newName) { _name = newName; } Dog.newBorn() { _name = "哈巴狗"; age = 0; } bark() { print("Bow Wow"); } _hiddenMethod() { print("I can only be called internally!"); } }5.7 靜態(tài)方法
如果想讓方法或者屬性靜態(tài)化,只需要在聲明前添加static關(guān)鍵字。
void test() { Dog.bark(); } class Dog { static bark() { print("Bow Wow"); } }5.8 泛型
dart全面支持泛型。假設(shè)你想在你定義的類(lèi)中,想持有任意類(lèi)型的數(shù)據(jù)。如下是怎樣使用泛型定義這樣的類(lèi)。
DataHolder06.Dart異步解讀 6.1 Future簡(jiǎn)單介紹dataHolder = new DataHolder("Some data"); print(dataHolder.getData()); dataHolder.setData("New Data"); print(dataHolder.getData()); //下面這個(gè)會(huì)報(bào)錯(cuò),因?yàn)閐ataHolder對(duì)象在創(chuàng)建的時(shí)候就已經(jīng)限制為String類(lèi)型 dataHolder.setData(123); print(dataHolder.getData()); class DataHolder { T data; DataHolder(this.data); getData() { return data; } setData(data) { this.data = data; } }
async 庫(kù)中有一個(gè)叫Future的東西。Future是基于觀察者模式的。如果你熟悉Rx或者JavaScript的Promises,你就很容易明白了。
首先先看一下下面的案例,看看它們之間有什么區(qū)別?
void testA() async{ new Future(() { return "This is a doubi"; }); } Future testB() async{ return new Future (() { return "This is a doubi"; }); } Future testC() { return new Future (() { return "This is a doubi"; }); }
Future是支持泛型的,例如Future,通過(guò)T指定將來(lái)返回值的類(lèi)型。
定義了一個(gè)叫g(shù)etTest的函數(shù),返回值為Future
當(dāng)調(diào)用了getTest方法,他返回Future
void test() { getTest().then((value) { print("測(cè)試----------"+value); }).catchError((error) { print("測(cè)試----------Error"); }); } FuturegetTest() { return new Future (() { return "This is a doubi"; }); } //打印結(jié)果 2019-06-21 17:11:12.941 16501-16583/com.hwmc.auth I/flutter: 測(cè)試----------This is a doubi
下面這個(gè)案例會(huì)發(fā)生異常
void test() { getTest().then((value) { print("測(cè)試----------"+value); }).catchError((error) { print("測(cè)試----------Error"); }); } FuturegetTest() { return new Future (() { return "This is a doubi"; }); } //打印結(jié)果 2019-06-21 17:18:46.896 16501-16583/com.hwmc.auth I/flutter: 測(cè)試----------Error
在生產(chǎn)環(huán)境中都是一些耗時(shí)的操作,例如,網(wǎng)絡(luò)調(diào)用,我們可以使用Future.delayed()模仿。
現(xiàn)在如果你運(yùn)行,你將需要2秒,才能返回結(jié)果。
void test() { getTest().then((value) { print("測(cè)試----------"+value); }).catchError((error) { print("測(cè)試----------Error"); }); } FuturegetTest() { return new Future .delayed(new Duration(milliseconds: 2000),() { return "This is a doubi"; }); }
接下來(lái)再看一個(gè)案例。在調(diào)用函數(shù)之后,我們添加了print語(yǔ)句。在這種場(chǎng)景中,print語(yǔ)句會(huì)先執(zhí)行,之后future的返回值才會(huì)打印。這是future的預(yù)期行為.但是如果我們希望在執(zhí)行其他語(yǔ)句之前,先執(zhí)行future。
void test() { getTest().then((value) { print("測(cè)試----------"+value); }).catchError((error) { print("測(cè)試----------Error"); }); print("測(cè)試----------逗比是這個(gè)先執(zhí)行嗎"); } Future6.2 async/await介紹getTest() { return new Future .delayed(new Duration(milliseconds: 2000),() { return "This is a doubi"; }); } 2019-06-21 17:26:16.619 16501-16583/com.hwmc.auth I/flutter: 測(cè)試----------逗比是這個(gè)先執(zhí)行嗎 2019-06-21 17:26:17.176 16501-16583/com.hwmc.auth I/flutter: 測(cè)試----------This is a doubi
思考一下,看了上面的案例,對(duì)于future的預(yù)期行為,如果我們希望在執(zhí)行其他語(yǔ)句之前,先執(zhí)行future,該怎么操作呢?
這就需要用到需要用到async/await。在test函數(shù)的花括號(hào)開(kāi)始添加async關(guān)鍵字。我們添加await關(guān)鍵字在調(diào)用getTest方法之前,他所做的就是在future返回值之后,繼續(xù)往下執(zhí)行。我們將整個(gè)代碼包裹在try-catch中,我們想捕獲所有的異常,和之前使用catchError回調(diào)是一樣。使用awiat關(guān)鍵字,必須給函數(shù)添加async關(guān)鍵字,否則沒(méi)有效果。
注意:要使用 await,其方法必須帶有 async 關(guān)鍵字。可以使用 try, catch, 和 finally 來(lái)處理使用 await 的異常!
Future test() async { try { String value = await getTest(); print("測(cè)試----------"+value); } catch(e) { print("測(cè)試----------Error"); } print("測(cè)試----------逗比是這個(gè)先執(zhí)行嗎"); } Future6.3 看一個(gè)案例getTest() { return new Future .delayed(new Duration(milliseconds: 2000),() { return "This is a doubi"; }); } 2019-06-21 17:32:37.701 16501-16583/com.hwmc.auth I/flutter: 測(cè)試----------This is a doubi 2019-06-21 17:32:37.702 16501-16583/com.hwmc.auth I/flutter: 測(cè)試----------逗比是這個(gè)先執(zhí)行嗎
一個(gè) async 方法 是函數(shù)體被標(biāo)記為 async 的方法。 雖然異步方法的執(zhí)行可能需要一定時(shí)間,但是 異步方法立刻返回 - 在方法體還沒(méi)執(zhí)行之前就返回了。
void getHttp async { // TODO --- }
在一個(gè)方法上添加 async 關(guān)鍵字,則這個(gè)方法返回值為 Future。
例如,下面是一個(gè)返回字符串的同步方法:
String loadAppVersion() => "1.0.2"
使用 async 關(guān)鍵字,則該方法返回一個(gè) Future,并且 認(rèn)為該函數(shù)是一個(gè)耗時(shí)的操作。
FutreloadAppVersion() async => "1.0.2"
注意,方法的函數(shù)體并不需要使用 Future API。 Dart 會(huì)自動(dòng)在需要的時(shí)候創(chuàng)建 Future 對(duì)象。
好的代碼是這樣的
void main() { //調(diào)用異步方法 doAsync(); } // 在函數(shù)上聲明了 async 表明這是一個(gè)異步方法 FuturedoAsync() async { try { // 這里是一個(gè)模擬請(qǐng)求一個(gè)網(wǎng)絡(luò)耗時(shí)操作 var result = await getHttp(); //請(qǐng)求出來(lái)的結(jié)果 return printResult(result); } catch (e) { print(e); return false; } } //將請(qǐng)求出來(lái)的結(jié)果打印出來(lái) Future printResult(summary) { print(summary); } //開(kāi)始模擬網(wǎng)絡(luò)請(qǐng)求 等待 5 秒返回一個(gè)字符串 getHttp() { return new Future.delayed(Duration(seconds: 5), () => "Request Succeeded"); }
不好的寫(xiě)法
void main() { doAsync(); } Future07.Dart異常捕獲 7.1 異常處理形式doAsync() async { return getHttp().then((r){ return printResult(r); }).catchError((e){ print(e); }); } Future printResult(summary) { print(summary); } Future getHttp() { return new Future.delayed(Duration(seconds: 5), () => "Request Succeeded"); }
dart 使用經(jīng)典的try-catch處理異常,使用關(guān)鍵字throw拋出一個(gè)異常。
7.2 拋出異常
看看如何拋出異常
void test1(){ divide(10, 0); } divide(int a, int b) { if (b == 0) { throw new IntegerDivisionByZeroException(); } return a / b; }
當(dāng)b變量的值為0的時(shí)候,拋出一個(gè)內(nèi)置的異常IntegerDivisionByZeroException。
如何定義異常日志呢?
可以在異常中攜帶一個(gè)字符串信息。
void test1(){ divide(10, 0); } divide(int a, int b) { if (b == 0) { throw new Exception("逗比,不能為0的"); } return a / b; }7.3 捕獲異常
某種類(lèi)型的異常可以通過(guò)on關(guān)鍵字捕獲,如下:
void test1(){ try { divide(10, 0); } on IntegerDivisionByZeroException { print("逗比,異常被捕獲了"); } } divide(int a, int b) { if (b == 0) { throw new IntegerDivisionByZeroException(); } return a / b; }
注意問(wèn)題,捕獲的異常層級(jí)要大于拋出的異常,否則捕獲會(huì)失敗
還是會(huì)拋出異常"逗比,不能為0的",因?yàn)镋xception比IntegerDivisionByZeroException層級(jí)要高。
void test1(){ try { divide(10, 0); } on IntegerDivisionByZeroException { print("逗比,異常被捕獲了"); } } divide(int a, int b) { if (b == 0) { throw new Exception("逗比,不能為0的"); } return a / b; }
如果你不知道拋出異常的類(lèi)型,或者不確定,可以使用catch塊處理任意類(lèi)型的異常。
void test1(){ try { divide(10, 0); } on IntegerDivisionByZeroException { print("逗比,異常被捕獲了"); } catch (e) { print(e); } } divide(int a, int b) { if (b == 0) { throw new Exception("yc other exception."); } return a / b; }7.4 Finally講解
dart也提供了finally塊,即是否發(fā)生異常這個(gè)塊都會(huì)執(zhí)行。
void test1(){ try { divide(10, 0); } on IntegerDivisionByZeroException { print("逗比,異常被捕獲了"); } catch (e) { print(e); }finally { print("I will always be executed!"); } } divide(int a, int b) { if (b == 0) { throw new Exception("yc other exception."); } return a / b; }08.Dart枚舉 8.1 枚舉使用
dart 支持枚舉,用法和java一樣。
Dog d = new Dog("哈巴狗", 12, CurrentState.sleeping); print(d.state == CurrentState.sleeping); //Prints "true" enum CurrentState { sleeping, barking, eating, walking } class Dog { String name; int age; CurrentState state; Dog(this.name, this.age, this.state); static bark() { print("Bow Wow"); } }8.2 元數(shù)據(jù)
使用元數(shù)據(jù)給代碼添加額外信息,元數(shù)據(jù)注解是以@字符開(kāi)頭,后面是一個(gè)編譯時(shí)常量或者調(diào)用一個(gè)常量構(gòu)造函數(shù)。
有三個(gè)注解所有的Dart代碼都可使用:@deprecated、@override,@proxy,下面直接上@deprecated的示例:
元數(shù)據(jù)可以在library、typedef、type parameter、constructor、factory、function、field、parameter、或者variable聲明之前使用,也可以在import或者export指令之前使用,使用反射可以再運(yùn)行時(shí)獲取元數(shù)據(jù)信息。
8.3 自定義注解
定義自己的元數(shù)據(jù)注解。下面的示例定義一個(gè)帶有兩個(gè)參數(shù)的@toDo注解:
void test1() { doSomething(); } @toDo("seth", "make this do something") void doSomething() { print("do something"); } class toDo { final String who; final String what; const toDo(this.who, this.what); }09.Dart字符串 9.1 String簡(jiǎn)單介紹
Dart字符串是UTF-16編碼的字符序列,可以使用單引號(hào)或者雙引號(hào)來(lái)創(chuàng)建字符串:
String str1 = "單引號(hào)字符串"; String str2 = "雙引號(hào)字符串"; print(str1); //輸出:?jiǎn)我?hào)字符串 print(str2); //輸出:雙引號(hào)字符串9.2 單雙引號(hào)互相嵌套
String中單、雙引號(hào)互相嵌套情況如下所示
String str1 = "單引號(hào)中的"雙引號(hào)"字符串"; String str2 = "雙引號(hào)中的"單引號(hào)"字符串"; print("yc-str1--" + str1); print("yc-str2--" + str2); //單引號(hào)里面有單引號(hào),必須在前面加反斜杠 String str3 = "單引號(hào)中的"單引號(hào)""; String str4 = "雙引號(hào)里面有雙引號(hào),"雙引號(hào)""; print("yc-str3--" + str3); print("yc-str4--" + str4);
打印值
2019-06-21 17:52:07.722 16501-16583/com.hwmc.auth I/flutter: yc-str1--單引號(hào)中的"雙引號(hào)"字符串 2019-06-21 17:52:07.723 16501-16583/com.hwmc.auth I/flutter: yc-str2--雙引號(hào)中的"單引號(hào)"字符串 2019-06-21 17:52:07.723 16501-16583/com.hwmc.auth I/flutter: yc-str3--單引號(hào)中的"單引號(hào)" 2019-06-21 17:52:07.723 16501-16583/com.hwmc.auth I/flutter: yc-str4--雙引號(hào)里面有雙引號(hào),"雙引號(hào)"
注意點(diǎn)::
單引號(hào)嵌套單引號(hào)之間不允許出現(xiàn)空串(不是空格),雙引號(hào)嵌套雙引號(hào)之間不允許出現(xiàn)空串:
//String str5 = "單引號(hào)""""單引號(hào)"; //報(bào)錯(cuò)了,逗比 String str6 = "單引號(hào)"" ""單引號(hào)"; String str7 = "單引號(hào)""*""單引號(hào)"; String str8 = "雙引號(hào)"" ""雙引號(hào)"; String str9 = "雙引號(hào)""*""雙引號(hào)"; //String str10 = "雙引號(hào)""""雙引號(hào)"; //報(bào)錯(cuò)了,逗比 print("yc-str6--" + str6); print("yc-str7--" + str7); print("yc-str8--" + str8); print("yc-str9--" + str9);
打印值
2019-06-21 17:56:21.847 16501-16583/com.hwmc.auth I/flutter: yc-str6--單引號(hào) 單引號(hào) 2019-06-21 17:56:21.847 16501-16583/com.hwmc.auth I/flutter: yc-str7--單引號(hào)*單引號(hào) 2019-06-21 17:56:21.847 16501-16583/com.hwmc.auth I/flutter: yc-str8--雙引號(hào) 雙引號(hào) 2019-06-21 17:56:21.847 16501-16583/com.hwmc.auth I/flutter: yc-str9--雙引號(hào)*雙引號(hào)其他介紹 01.關(guān)于博客匯總鏈接
1.技術(shù)博客匯總
2.開(kāi)源項(xiàng)目匯總
3.生活博客匯總
4.喜馬拉雅音頻匯總
5.其他匯總
02.關(guān)于我的博客github:https://github.com/yangchong211
知乎:https://www.zhihu.com/people/...
簡(jiǎn)書(shū):http://www.jianshu.com/u/b7b2...
csdn:http://my.csdn.net/m0_37700275
喜馬拉雅聽(tīng)書(shū):http://www.ximalaya.com/zhubo...
開(kāi)源中國(guó):https://my.oschina.net/zbj161...
泡在網(wǎng)上的日子:http://www.jcodecraeer.com/me...
郵箱:yangchong211@163.com
阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
segmentfault頭條:https://segmentfault.com/u/xi...
掘金:https://juejin.im/user/593943...
博客匯總項(xiàng)目開(kāi)源地址:https://github.com/yangchong2...文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/75099.html
摘要:工具可以報(bào)告兩種問(wèn)題警告和錯(cuò)誤。警告只是說(shuō)明代碼可能無(wú)法正常工作,但不會(huì)阻止程序執(zhí)行。中的是一組無(wú)序的集合。其中來(lái)指定異常類(lèi)型,來(lái)捕獲異常對(duì)象。其中代表只導(dǎo)入指定的部分,代表除了指定的部分都導(dǎo)入。 本文首發(fā)于微信公眾號(hào)「劉望舒」 前言 Dart是Flutter SDK指定的語(yǔ)言,因此要學(xué)習(xí)Flutter,Dart是必須掌握的。關(guān)于Dart可以寫(xiě)一本書(shū)了,這里用一篇文章來(lái)介紹下Dart的精...
摘要:月日,谷歌正式發(fā)布了的。到底能不能成為跨平臺(tái)開(kāi)發(fā)終極之選是基于前端誕生的,但是對(duì)前端開(kāi)發(fā)來(lái)說(shuō),的環(huán)境配置很麻煩,需要原生的平臺(tái)知識(shí),還要擔(dān)心遇上網(wǎng)絡(luò)問(wèn)題。現(xiàn)在已經(jīng)不是曾經(jīng)的小眾框架,這兩年里它已經(jīng)逐步成長(zhǎng)為主流的跨平臺(tái)開(kāi)發(fā)框架之一。 ...
摘要:注釋處的方法是程序的入口,使用了符號(hào),這是中單行函數(shù)或方法的簡(jiǎn)寫(xiě),等價(jià)于如下代碼方法是框架的入口,如果不返回方法,那么執(zhí)行的是一個(gè)控制臺(tái)應(yīng)用。 本文首發(fā)于微信公眾號(hào)「劉望舒」 前言 最近的Google I/O大會(huì)上,F(xiàn)lutter1.5 開(kāi)始支持移動(dòng)、Web、桌面和嵌入式設(shè)備,從不溫不火的sky一直進(jìn)化到如今熱門(mén)的Flutter,F(xiàn)lutter的發(fā)展已經(jīng)超出很多人的想象。我對(duì)跨平臺(tái)技術(shù)一...
摘要:在去年大展上發(fā)布首個(gè)版后,正式版于年月召開(kāi)的上正式發(fā)布。今天在巴塞羅那召開(kāi)的發(fā)布會(huì)上,正式發(fā)布了跨平臺(tái)框架的版本。支持此版本包括,該也于昨天發(fā)布。除了,團(tuán)隊(duì)還發(fā)布了的預(yù)覽版,這是一套用于和的性能工具。 在去年 MWC 大展上發(fā)布首個(gè) Beta 版后,F(xiàn)lutter 1.0 正式版于 2018 年 12 月召開(kāi)的 Flutter Live 2018 上正式發(fā)布。今天在巴塞羅那召開(kāi)的 MW...
閱讀 858·2021-11-24 10:44
閱讀 2797·2021-11-11 16:54
閱讀 3210·2021-10-08 10:21
閱讀 2109·2021-08-25 09:39
閱讀 2916·2019-08-30 15:56
閱讀 3471·2019-08-30 13:46
閱讀 3504·2019-08-23 18:09
閱讀 2097·2019-08-23 17:05