Dart學(xué)習(xí)基礎(chǔ)之第二篇

Mixin


此圖可以簡單的描述一下類的繼承

備注:子類沒有重寫超類A方法的前提下,如果2個(gè)或多個(gè)超類擁有相同簽名的A方法瑟俭,那么子類會(huì)以繼承的最后一個(gè)超類中的A方法為準(zhǔn)障斋。

如果子類自己重寫了A方法則以本身的A方法為準(zhǔn)。


泛型-泛型函數(shù)

main() {

? K addCache<K, V>(K key, V value) {

? ? K temp = key;

? ? print('${key}: ${value}');

? ? return temp;

? }

? var key = addCache('dongnao', 'damon');

? print(key);

}

備注:Dart1.21開始可以使用泛型函數(shù)泪掀。

泛型函數(shù)可以在以下幾個(gè)地方使用類型參數(shù):

? ? ? ? <1>? ? 函數(shù)的返回值類型听绳。

? ? ? ? <2>? ? 參數(shù)的類型。

? ? ? ? <3>? ? 局部變量的類型异赫。


泛型-構(gòu)造函數(shù)泛型

main() {

? var p = Phone<String>('123456');

? print(p.mobileNumber);

}

class Phone<T> {

? final T mobileNumber;

? Phone(this.mobileNumber);

}

備注:Dart1.21開始可以使用泛型函數(shù)椅挣。

泛型函數(shù)可以在以下幾個(gè)地方使用類型參數(shù):

? ? ? ? <1>? ? 函數(shù)的返回值類型。

? ? ? ? <2>? ? 參數(shù)的類型塔拳。

? ? ? ? <3>? ? 局部變量的類型贴妻。


泛型-泛型限制

main() {

? var footMassage = FootMassage();

? var m = Massage<FootMassage>(footMassage);

? m.massage.doMassage();

}

class Massage<T extends FootMassage > {

? final T massage;

? Massage(this.massage);

}

class FootMassage {

? void doMassage() {

? ? print('腳底按摩');

? }

}

備注:實(shí)現(xiàn)泛型類型時(shí),您可能希望限制其參數(shù)的類型蝙斜,可以在<>里面使用extends名惩。


泛型-與java區(qū)別

Java中的泛型信息是編譯時(shí)的,泛型信息在運(yùn)行時(shí)是不存在的

Dart的泛型類型是固化的孕荠,在運(yùn)行時(shí)也有可以判斷的具體類型

var names = List<String>();

print(names is List<String>);//true

print(names.runtimeType); // List<String>

備注:在Java中娩鹉,可以測試對(duì)象是否為List,但無法測試它是否是List<String>稚伍。

庫-使用核心庫

使用import關(guān)鍵字來載入庫:

import "dart:math";

void main() {

? print(sqrt(4));//開平方 2.0

}

備注:import 后的必須參數(shù)為庫 的 URI弯予。(Uniform?Resource?Identifier統(tǒng)一資源標(biāo)識(shí)符)

對(duì)于內(nèi)置的庫,URI 使用特殊的 dart: scheme个曙。

對(duì)于其他的庫锈嫩,你可以使用文件系統(tǒng)路徑或者 package: scheme。


庫-載入第三方庫

1.編寫pubspec.yaml:
dependencies:

? flutter:

? ? sdk: flutter

? cupertino_icons: ^0.1.0

? dio: ^2.1.0

2.調(diào)用

import "package:dio/dio.dart";

void main() {

? getHttp();

}

void getHttp() async {

? try {

? ? Response response = await Dio().get("https://www.baidu.com");

? ? print(response);

? } catch (e) {

? ? print(e);

? }

}

庫-指定庫前綴

如果兩個(gè)庫有沖突的標(biāo)識(shí)符垦搬,可以為其中一個(gè)或兩個(gè)庫都指定前綴:

import 'MyLib1.dart' as lib1;

import 'MyLib2.dart' as lib2;

void main() {

? var myLib = lib1.MyLib();

? var myLib2 = lib2.MyLib();

}

庫-選擇性載入

show-只載入庫的某些部分

hide-篩選掉庫的某些部分

import 'Mylib1.dart' as lib1 show Test;

import 'Mylib2.dart' as lib2 hide Test;

var test = lib1.Test();

var lib = lib2.MyLib();

備注:果只使用庫的一部分功能呼寸,則可以選擇需要導(dǎo)入的 內(nèi)容。

庫-延遲載入

使用deferred as導(dǎo)入

使用標(biāo)識(shí)符調(diào)用loadLibrary()加載庫

import 'MyLib1.dart' deferred as lazyLib;

void main() {

? lazyLoad();

}

lazyLoad() async {

? await lazyLib.loadLibrary();

? var t = lazyLib.Test();

? t.test();

}

備注:使用 await 關(guān)鍵字暫停代碼執(zhí)行一直到庫加載完成猴贰。

可提高程序啟動(dòng)速度对雪。

用在不常使用的功能。

用在載入時(shí)間過長的包米绕。

執(zhí)行 A/B 測試瑟捣,例如 嘗試各種算法的 不同實(shí)現(xiàn)。

庫-自定義庫

1.//mylib/mylib.dart

library mylib;

part 'util.dart';

part 'tool.dart';

void printMyLib() => print('mylib');


2.//mylib/tool.dart

part of mylib;

void printTool() => print('tool');

3.import 'mylib/mylib.dart';

void main() {

? printMyLib();

? printUtil();

? printTool();

}

備注:part 可以把一個(gè)庫分開到多個(gè) Dart 文件中栅干。

或者我們想讓某一些庫共享它們的私有對(duì)象的時(shí)候迈套,可以需要使用part。

import不會(huì)完全共享作用域碱鳞,而part之間是完全共享的桑李。如果說在A庫中import了B庫,B庫import了C庫,A庫是沒有辦法直接使用C庫的對(duì)象的芙扎。而B,C若是A的part,那么三者共享所有對(duì)象填大。并且包含所有導(dǎo)入戒洼。


異步-async和await

void main(){

? getName1();

? getName2();

? getName3();

}

Future getName1() async {

? await getStr1();

? await getStr2();

? print('getName1’);

}

getStr1() {

? print('getStr1’);

}

getStr2() {

? print('getStr2’);

}

getName2() {

? print('getName2’);

}

getName3() {

? print('getName3’);

}

備注:await關(guān)鍵字必須在async函數(shù)內(nèi)部使用

await表達(dá)式可以使用多次


異步-then,catchError,whenComplete

void main() {

? new Future(() => futureTask())//異步任務(wù)的函數(shù)

? ? ? .then((m) => "result:$m")//任務(wù)執(zhí)行完后的子任務(wù)

? ? ? .then((m) => m.length) //其中m為上個(gè)任務(wù)執(zhí)行完后的返回的結(jié)果

? ? ? .then((m) => printLength(m))

? .catchError(print)

? ? ? .whenComplete(() => whenTaskCompelete());//所有任務(wù)完成后的回調(diào)函數(shù)

}

備注:

如果需要監(jiān)聽“完畢”這個(gè)狀態(tài),那么用whenComplete,需要監(jiān)聽“成功”這個(gè)狀態(tài)允华,用then圈浇,需要監(jiān)聽“失敗”這個(gè)狀態(tài),用catchError靴寂。

如果重寫了test方法磷蜀,test返回true就可以在catchError的onError方法里捕獲到異常,如果test返回false百炬,就把該異常繼續(xù)拋出而不會(huì)在catchError方法里被捕獲褐隆,如果不寫test默認(rèn)實(shí)現(xiàn)一個(gè)返回true的test方法


異步-Event-Looper


備注:一個(gè)消息循環(huán)的職責(zé)就是不斷從消息隊(duì)列中取出消息并處理他們直到消息隊(duì)列為空。

消息隊(duì)列中的消息可能來自用戶輸入剖踊,文件I/O消息庶弃,定時(shí)器等。例如上圖的消息隊(duì)列就包含了定時(shí)器消息和用戶輸入消息德澈。

Dart中的Main Isolate只有一個(gè)Event Looper歇攻,但是存在兩個(gè)Event Queue: Event Queue以及Microtask Queue。

異步-Event Queue和Microtask Queue


備注:優(yōu)先全部執(zhí)行完Microtask Queue中的Event梆造。

直到Microtask Queue為空時(shí)缴守,才會(huì)執(zhí)行Event Queue中的Event。

當(dāng)Event Looper正在處理Microtask Queue中的Event時(shí)候镇辉,Event Queue中的Event就停止了處理了屡穗,此時(shí)App不能繪制任何圖形,不能處理任何鼠標(biāo)點(diǎn)擊忽肛,不能處理文件IO等等鸡捐。

繪制圖形,處理鼠標(biāo)點(diǎn)擊麻裁,處理文件IO等都是在Event Queue里完成的箍镜。

異步-任務(wù)調(diào)度

使用Future類,可以將任務(wù)加入到Event Queue的隊(duì)尾

使用scheduleMicrotask函數(shù)煎源,將任務(wù)加入到Microtask Queue隊(duì)尾


異步-new Future()

void main(){

? testFuture();

}

void testFuture() {

? Future f = new Future(() => print('f1'));

? Future f1 = new Future(() => null);

? //Future f1 = new Future.delayed(Duration(seconds: 1) ,() => null);

? Future f2 = new Future(() => null);

? Future f3 = new Future(() => null);

? f3.then((_) => print('f2'));

? f2.then((_) {

? ? print('f3');

? ? new Future(() => print('f4'));

? ? f1.then((_) {

? ? ? print('f5');

? ? });

? });

? f1.then((m) {

? ? print('f6');

? });

? print('f7');

}

備注:使用new Future將任務(wù)加入event隊(duì)列色迂。

Future中的then并沒有創(chuàng)建新的Event丟到Event Queue中,而只是一個(gè)普通的Function Call手销,在FutureTask執(zhí)行完后歇僧,立即開始執(zhí)行。

如果在then()調(diào)用之前Future就已經(jīng)執(zhí)行完畢了,那么任務(wù)會(huì)被加入到microtask隊(duì)列中诈悍,并且該任務(wù)會(huì)執(zhí)行then()中注冊的回調(diào)函數(shù)祸轮。

使用Future.value構(gòu)造函數(shù)的時(shí)候,就會(huì)上一條一樣侥钳,創(chuàng)建Task丟到microtask Queue中執(zhí)行then傳入的函數(shù)适袜。

Future.sync構(gòu)造函數(shù)執(zhí)行了它傳入的函數(shù)之后,也會(huì)立即創(chuàng)建Task丟到microtask Queue中執(zhí)行舷夺。

當(dāng)任務(wù)需要延遲執(zhí)行時(shí)苦酱,可以使用new Future.delay()來將任務(wù)延遲執(zhí)行。


異步-scheduleMicrotask()

import 'dart:async';

void main(){

? testFuture();

}

void testScheduleMicrotask(){

? scheduleMicrotask(() => print('s1'));

? new Future.delayed(new Duration(seconds: 1), () => print('s2'));

? new Future(() => print('s3')).then((_) {

? ? print('s4');

? ? scheduleMicrotask(() => print('s5'));

? }).then((_) => print('s6'));

? new Future(() => print('s7'));

? scheduleMicrotask(() => print('s8'));

? print('s9');

}

備注:如果可以给猾,盡量將任務(wù)放入event隊(duì)列中疫萤。

使用Future的then方法或whenComplete方法來指定任務(wù)順序。

為了保持你app的可響應(yīng)性敢伸,盡量不要將大計(jì)算量的任務(wù)放入這兩個(gè)隊(duì)列扯饶。

大計(jì)算量的任務(wù)放入額外的isolate中。

生成器-同步生成器

Main(){

? var it = getSyncGenerator(5).iterator;

? while (it.moveNext()) {

? ? print(it.current);

? }

}

Iterable<int> getSyncGenerator(int n) sync* {

? print('start');

? int k = 0;

? while (k < n) {

? ? yield k++;

? }

? print('end');

}

備注:使用sync*池颈,返回的是Iterable對(duì)象帝际。

yield會(huì)返回moveNext為true,并等待 moveNext 指令。

調(diào)用getSyncGenerator立即返回Iterable對(duì)象饶辙。

調(diào)用moveNext方法時(shí)getSyncGenerator才開始執(zhí)行蹲诀。

生成器-異步生成器

Main(){

//getAsyncGenerator(5).listen((value) => print(value));

? StreamSubscription subscription = getAsyncNumIterator(5).listen(null);

? subscription.onData((value) {

? ? print(value);

? ? if(value>=2){

? ? ? subscription.pause();

? ? }

? });

}

Stream<int> getAsyncGenerator(int n) async* {

? print('start');

? int k = 0;

? while (k < n) {

yield k++;

? }

? print('end');

}

備注:使用async*,返回的是Stream對(duì)象弃揽。

yield不用暫停脯爪,數(shù)據(jù)以流的方式一次性推送,通過StreamSubscription進(jìn)行控制。

調(diào)用getAsyncGenerator立即返回Stream,只有執(zhí)行了listen矿微,函數(shù)才會(huì)開始執(zhí)行痕慢。

listen返回一個(gè)StreamSubscription 對(duì)象進(jìn)行流監(jiān)聽控制。

可以使用StreamSubscription對(duì)象對(duì)數(shù)據(jù)流進(jìn)行控制涌矢。

生成器-遞歸生成器

Main(){

? var it = getSyncRecursiveGenerator(5).iterator;

? while (it.moveNext()) {

? ? print(it.current);

? }

}

Iterable<int> getSyncRecursiveGenerator(int n) sync* {

? if (n > 0) {

? ? yield n;

? ? yield* getSyncNumDownFrom(n - 1);

? }

}

備注:yield* 以指針的方式傳遞遞歸對(duì)象掖举,而不是整個(gè)同步對(duì)象。

隔離-Isolates

所有Dart代碼都在隔離區(qū)內(nèi)運(yùn)行娜庇,而不是線程塔次。每個(gè)隔離區(qū)都有自己的內(nèi)存堆,確保不會(huì)從任何其他隔離區(qū)訪問隔離區(qū)的狀態(tài)名秀。

備注:Dart沒有共享內(nèi)存的并發(fā)励负,沒有競爭的可能性所以不需要鎖,也就不用擔(dān)心死鎖的問題匕得。

isolate之間沒有共享內(nèi)存继榆,所以他們之間的通信唯一方式只能是通過Port進(jìn)行,而且Dart中的消息傳遞總是異步的。

isolate神似Thread略吨,但實(shí)際上兩者有本質(zhì)的區(qū)別集币。操作系統(tǒng)內(nèi)的線程之間是可以有共享內(nèi)存的而isolate沒有,這是最為關(guān)鍵的區(qū)別翠忠。

元數(shù)據(jù)(注解)-@deprecated

main() {

? dynamic tv = new Television();

? tv.activate();

? tv.turnOn();

}

class Television {

? @deprecated

? void activate() {

? ? turnOn();

? }

? void turnOn() {

? ? print('Television turn on!');

? }

}

備注:所有的 Dart 代碼都可以使用: @deprecated 和 @override鞠苟。

元數(shù)據(jù)(注解)-自定義


備注:在java中,如果自定義一個(gè)注解负间,需要添加 @Target 作用域注解,@Retention 注解類型注解姜凄,添加 @interface政溃,然后定義注解參數(shù)。

構(gòu)造方法定義為編譯時(shí)常量

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末态秧,一起剝皮案震驚了整個(gè)濱河市董虱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌申鱼,老刑警劉巖愤诱,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異捐友,居然都是意外死亡淫半,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門匣砖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來科吭,“玉大人,你說我怎么就攤上這事猴鲫《匀耍” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵拂共,是天一觀的道長牺弄。 經(jīng)常有香客問我,道長宜狐,這世上最難降的妖魔是什么势告? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮抚恒,結(jié)果婚禮上培慌,老公的妹妹穿的比我還像新娘。我一直安慰自己柑爸,他們只是感情好吵护,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般馅而。 火紅的嫁衣襯著肌膚如雪祥诽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天瓮恭,我揣著相機(jī)與錄音雄坪,去河邊找鬼。 笑死屯蹦,一個(gè)胖子當(dāng)著我的面吹牛维哈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播登澜,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼阔挠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了脑蠕?” 一聲冷哼從身側(cè)響起购撼,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎谴仙,沒想到半個(gè)月后迂求,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡晃跺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年揩局,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掀虎。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡谐腰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出涩盾,到底是詐尸還是另有隱情十气,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布春霍,位于F島的核電站砸西,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏址儒。R本人自食惡果不足惜芹枷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望莲趣。 院中可真熱鬧鸳慈,春花似錦、人聲如沸喧伞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至翁逞,卻和暖如春肋杖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挖函。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工状植, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人怨喘。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓津畸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親必怜。 傳聞我的和親對(duì)象是個(gè)殘疾皇子肉拓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容