dart 語法進(jìn)階

1. 接口 abstract implements java 中是interface

abstract class Processor {
  late String cores;
  arch(String name) {}
}

abstract class Camera {
  late String resolution;
  brand(String name);
}

class Phone implements Processor, Camera {
  @override
  arch(String name) {
    print(name);
  }

  @override
  brand(String name) {
    print(name);
  }

  @override
  String cores;

  @override
  String resolution;

  Phone()
      : cores = '3',
        resolution = 'name';
}

void main() {
  print("hello world");

  var phone = Phone();
}

2. mixin 提高代碼的復(fù)用度

  • class mixin 關(guān)鍵字都可已推薦 mixin
  • with 可以是多個(gè) ”,“ 分割,后面的屬性和方法重名會(huì)覆蓋前面的
  • 用作混入的類不能有構(gòu)造函數(shù)
  • mixin 類只能繼承 Object
//  class  mixin
class MixinA {
  String name = 'MixinA';
  void showInfo() {
    print(name);
  }
}

mixin MixinB {
  // MixinB(); 用作混入的類不能有構(gòu)造函數(shù)
  String name = 'MixinB';
  void showInfo() {
    print(name);
  }
}

class MixinTest with MixinA, MixinB {}

void main() {
  print("hello world");

  var mixinTest = MixinTest();
  print(mixinTest.name);
}

3. extension 擴(kuò)展

//擴(kuò)展內(nèi)置類
extension StringExt on String {
  int parseInt() {
    return int.parse(this);
  }
}

//擴(kuò)展自定義類
class Person {
  final String name;
  Person(this.name);
}

extension PersonExt on Person {
  info() {
    print(this.name);
  }
}

4. call

  • 在類中可以聲明call 方法

  • 類的實(shí)例當(dāng)做行數(shù)使用

    void main(List<String> args) {
      var phone = Phone();//將類的實(shí)例當(dāng)做函數(shù)使用
      phone('18614060661');
    }
    
    class Phone {
      call(String num) {
        print('phone number is $num');
      }
    }
    

5. noSuchMethod

class Person {
  final String name;
  Person(this.name);

  @override
  noSuchMethod(Invocation invocation) {
    return super.noSuchMethod(invocation);
  }
}

void main(List<String> args) {
  //dynamic 修飾
  dynamic p = Person('zhu');
  p.say();
}

6. hashCode

  • dart 對(duì)象的唯一標(biāo)識(shí)
  • 表現(xiàn)為一串?dāng)?shù)字 // eg: obj.hashCode; 608635269
  • 可以判斷兩個(gè)對(duì)象是否是同一個(gè)內(nèi)存地址

7. typedef

  • 自定義別名
  • 語法
    • typedef function_name (parmas)
    • typedef variable_name=List<int> (dart:2.13之后)
typedef MathOperation = Function(int a, int b);
fn1(int a, b) {
  return a + b;
}
void main(List<String> args) {
  if (fn1 is MathOperation) {
    print('true');
  } else {
    print('false');
  }
}

8.eventLoop 事件輪詢機(jī)制

image.png
image.png

9 isolate

  • isolate 是dart 中的線程
    • 每個(gè)isolate都有自己的獨(dú)立的私有內(nèi)存(多個(gè)isolate不共享內(nèi)存)
    • dart中的線程是以 隔離(isolate)的方式存在
    • 沒有共享沒存,不存在資源競爭(不需要鎖,也就沒有死鎖)
  • 所有dart 都運(yùn)行在isolate中
    • isolate 提供了dart | flutter 的運(yùn)行環(huán)境
    • 微任務(wù)隊(duì)列、事件隊(duì)列、事件輪詢 都在isolate 中進(jìn)行
  • 多線程長用來解決耗時(shí)較長的異步任務(wù)
  • isolate的位置
image.png
9.1 isolate 多線程-創(chuàng)建
  • Isolate 類 用來管理線程(創(chuàng)建、暫停、殺死 Isolate線程)

    Isolate.spawn();//創(chuàng)建線程
    Isolate.spawnUri();//跨文件 函數(shù)創(chuàng)建線程
    Isolate.pause();//暫停
    Isolate.kill();//殺死
    
import 'dart:isolate';
/*
entryPoint : 必須是一個(gè)頂層方法或靜態(tài)方法
message:
  1. dart 原始類型 eg:null,int,String ...
  2. SendPort 實(shí)例 ReceivePort().sendPort 
  3. 包含 1 和 2 的list、 map 可以嵌套

*/
static Future<Isolate> spawn<T>(void entryPoint(T message), T message);

 
import 'package:flutter/foundation.dart'
compute();
  • 使用實(shí)例1:創(chuàng)建一個(gè)線程

    import 'dart:isolate';   
    void main() {
      test();
    }
    void test() async {
      print('---start---');
      print('thead: ${Isolate.current.debugName}');
      Isolate.spawn(newThread1, 'zhu'); //一般 異步執(zhí)行  
      print('---end---');
      /*
      end 和 子線程打印順序不固定
    
      ---start---
      thead: main
      ---end---
      thead: newThread1  message:zhu
    
      ---start---
      thead: main
      thead: newThread1  message:zhu
      ---end---
        */
    }
    
    void newThread1(dynamic message) {
      print('thead: ${Isolate.current.debugName}  message:$message');
    }
    
  • 實(shí)例2 創(chuàng)建多個(gè)線程

    import 'dart:isolate';
    
    void main(List<String> args) {
      test();
    }
    
    void test() async {
      print('---start---');
      print('thead: ${Isolate.current.debugName}');
      Isolate.spawn(newThread1, 'zhu');
      Isolate.spawn(newThread2, true);
      Isolate.spawn(newThread3, 1000);
    
      print('---end---');
    }
    
    void newThread1(dynamic message) {
      print('thead: ${Isolate.current.debugName}  message:$message');
    }
    
    void newThread2(dynamic message) {
      print('thead: ${Isolate.current.debugName}  message:$message');
    }
    
    void newThread3(dynamic message) {
      print('thead: ${Isolate.current.debugName}  message:$message');
    }
    
    
9.2 多線程通信機(jī)制-Port
  • isolate 多線程之間通信的唯一方式是 Port

  • ReceivePort 類,初始化接受端口,創(chuàng)建發(fā)送端口,接受消息、監(jiān)聽消息、關(guān)閉端口

  • SendPort 類 將消息發(fā)送給ReceivePort

  • 通信方式

    • 單項(xiàng)通信:A -> B
    • 雙向通信:A <-> B
    • image.png
import 'dart:isolate';

void main(List<String> args) {
  test();
}

test() {
  print('---start---');
  print(Isolate.current.debugName);
  //創(chuàng)建接收端口
  ReceivePort receivePort = ReceivePort();
  //建立監(jiān)聽
  receivePort.listen((message) {
    print('listen: $message');

    //關(guān)閉監(jiān)聽
    receivePort.close();
  });

  //獲取發(fā)送端口
  SendPort sendPort = receivePort.sendPort;

  Isolate.spawn(mutilThead, sendPort);

  print('---end---');
}

void mutilThead(message) {
  print(Isolate.current.debugName);
  print(message);

  SendPort sendPort = message as SendPort;
  sendPort.send('mutilThead 發(fā)來的消息');
}
image.png
import 'dart:isolate';

void main(List<String> args) async {
  print('---start---');
  print(Isolate.current.debugName);
  //創(chuàng)建接收端口
  ReceivePort r1 = ReceivePort();
  //建立監(jiān)聽

  //獲取發(fā)送端口
  SendPort p1 = r1.sendPort;
  Isolate.spawn(newThead, p1);

  SendPort p2 = await r1.first;
  var msg = await sendToReceive(p2, 'hello');
  print('主線程接收到:$msg');

  print('---end---');
}

Future sendToReceive(SendPort sendPort, dynamic msg) async {
  print('${Isolate.current.debugName} 發(fā)送消息: $msg');
  ReceivePort receivePort = ReceivePort();
  sendPort.send([receivePort.sendPort, msg]);
  return receivePort.first;
}

void newThead(SendPort p1) async {
  var r2 = ReceivePort();
  p1.send(r2.sendPort);

  await for (var msg in r2) {
    var data = msg[1];
    print('新線程收到了主線程的消息:$data');
    SendPort replyPort = msg[0];

    //回復(fù)消息
    replyPort.send('子線程答復(fù)->$data');
  }
}
/*
 ---start---
main
main 發(fā)送消息: hello
新線程收到了主線程的消息:hello
主線程接收到:子線程答復(fù)->hello
---end--- 
 */

  • Isolate.spawnUri

    import 'dart:isolate';
    
    void main(List<String> args) {
      print('start');
      newIsolate();
      print('end');
    }
    
    void newIsolate() async {
      ReceivePort r1 = ReceivePort();
      SendPort p1 = r1.sendPort;
    
      var childThead = await Isolate.spawnUri(
          Uri(path: 'child_isolate.dart'), ['data1', 'data2', 'data3'], p1);
    
      r1.listen((message) {
        print('主線程收到消息:$message');
    
        if (message[0] == 0) {
          print('加載中');
        } else if (message[0] == 1) {
          print('處理中');
        } else if (message[0] == 2) {
          print('初始完成');
          r1.close();
          childThead.kill();
        }
      });
    }
    
    //child_isolate.dart
    
    import 'dart:io';
    import 'dart:isolate';
    
    void main(List<String> args, SendPort p1) {
      print('${Isolate.current.debugName} 收到:$args');
      p1.send([0, '加載中']);
      sleep(Duration(seconds: 1));
      p1.send([1, '處理中']);
      sleep(Duration(seconds: 1));
      p1.send([2, '處理完成']);
    }
    

10.Future (類似js 中的Promise)

10.1初始
  • 概念

    • Future 是dart 中的類,我們可以通過Future 實(shí)例封裝一些異步任務(wù)

    • Future 含義是未來。未來要執(zhí)行的任務(wù)可以放到Future中

  • Future 的三種狀態(tài)

    • 未完成 (Uncompleted)
    • 已完成,并返回?cái)?shù)據(jù)(Complete with data)
    • 已完成,但返回錯(cuò)誤(Complete with error)
  • 獲取實(shí)例

    • 自動(dòng)返回

      • final myFuture = http.get('http://xxxx')
      • final myFuture = SharePreferences.getInstace;
    • 手動(dòng)創(chuàng)建

      • final myFuture = Future((){return 123;});
      • final myFuture = Future.error(Exception());
      • Final myFuture = Future.delayed(Duration(seconds:3),(){return 123;});
  • 狀態(tài)相關(guān)方法

    • 創(chuàng)建
      • Uncomplete
    • then()
      • Complate with data
    • catchError()
      • Complate with error
    • whenComplate()
      • Complate with data + Complate with error
void main(List<String> args) {
  test();
}

void test() {
  print('start');
  var myFuture = Future.delayed(Duration(seconds: 3), () {
    throw '異常數(shù)據(jù)';
  });

  myFuture.then((value) => print(value)).catchError((error) {
    print('error : ' + error);
  }, test: (error) => error.runtimeType == String).whenComplete(
      () => print('complate'));
  print('end');
}
/*
start
end
error : 異常數(shù)據(jù)
complate
*/
10.2 Future執(zhí)行順序
  • Future 默認(rèn)是異步任務(wù),會(huì)被丟到事件隊(duì)列(event queue)中

  • Future.sync()

    • 同步任務(wù),同步執(zhí)行(不會(huì)丟到異步隊(duì)列)
  • Future.microtast()

    • 微任務(wù)丟到microtask queue 中優(yōu)先級(jí)比event queue 高
  • Future.value(val)

    • val 是常量 (等同microtask)

    • val 是異步(按照異步任務(wù)處理)

10.3 多任務(wù)
  • Future.any(Futures) 返回最先完成的Future結(jié)果

  • Future.wait(Futures) 等待所有的Future完成,并返回所有Future的結(jié)果

  • Future.doWhile(action) 按照條件遍歷執(zhí)行多個(gè)Future

  • Future.forEach(elements,action) 遍歷一個(gè)給定的集合,根據(jù)集合元素執(zhí)行多個(gè)Future

10.4. FutureBuilder - snapshot
  1. snapshot.connectionState
  • ConnectionState.none (未連接異步任務(wù))
  • ConnectionState.waiting (連接異步任務(wù),等待交互)
  • ConnectionState.active (連接異步任務(wù),正在交互)
  • ConnectionState.done (異步任務(wù)完成)
  1. snapshot.hasData

  2. snapshot.hasError

11.Stream

11.1 Stream 概念

Stream 是Dart 中異步數(shù)據(jù)流,可以連續(xù)不斷地返回多個(gè)數(shù)據(jù)。

  • Future是異步 ,單只返回一個(gè)值
  • Stream也是異步,可以返回多個(gè)值(數(shù)據(jù)流)

Stream 相關(guān)的API

  • 通過listen進(jìn)行數(shù)據(jù)監(jiān)聽
  • 通過error 接受失敗狀態(tài)
  • done來接收結(jié)束狀態(tài)
11.2 Stream 類型

Single-Subscription (單一訂閱)

  • 數(shù)據(jù)流只能listen 一次(listen 多次會(huì)報(bào)錯(cuò))
  • StreamController().stream
  • Stream stream = Stream.fromIterable(data)
import 'dart:async';

void main(List<String> args) {
  //創(chuàng)建一次訂閱數(shù)據(jù)流控制器
  StreamController streamController = StreamController();

  //一次監(jiān)聽 只能監(jiān)聽一次
  streamController.stream.listen((event) {
    print('接收到數(shù)據(jù):$event');
  });

  //sink數(shù)據(jù)槽 添加數(shù)據(jù)
  streamController.sink.add('123');
  streamController.sink.add('abc');
  /*
接收到數(shù)據(jù):123
接收到數(shù)據(jù):abc
  */
}

Broadcase (廣播)

  • 數(shù)據(jù)流可以被 listen 多次
  • StreamController<int>.broadcast();
  • stream.asBroadcastStream()
import 'dart:async';

void main(List<String> args) {
  //創(chuàng)建多次訂閱數(shù)據(jù)流控制器
  StreamController streamController = StreamController.broadcast();

  streamController.stream.listen((event) {
    print('第一次監(jiān)聽接收到數(shù)據(jù):$event');
  });

  //sink數(shù)據(jù)槽 添加數(shù)據(jù)
  streamController.sink.add('123');

  streamController.stream.listen((event) {
    print('第二次監(jiān)聽接收到數(shù)據(jù):$event');
  });
  streamController.sink.add('abc');

/*
第一次監(jiān)聽接收到數(shù)據(jù):123
第二次監(jiān)聽接收到數(shù)據(jù):abc
第一次監(jiān)聽接收到數(shù)據(jù):abc
*/
}

11.3 創(chuàng)建 Stream 實(shí)例

StreamController 類

  • sink
  • stream

Stream 類

  • Stream.fromFuture();
  • Stream.fromFutures();
  • Stream.fromIterable();
  • Stream.periodic();
Future<String> getFuture() async {
  await Future.delayed(Duration(seconds: 2), () {});
  return DateTime.now().toString();
}

void main(List<String> args) async {
  Stream.fromFuture(getFuture()).listen((event) {
    print('fromFuture 接收到數(shù)據(jù) : $event');
  }, onDone: () {
    print('fromFuture onDone');
  });

  Stream.fromFutures([getFuture(), getFuture(), getFuture()]).listen((event) {
    print('fromFutures 接收到數(shù)據(jù) : $event');
  });

  Stream.fromIterable([123, 'acb', null]).listen((event) {
    print('fromIterable 接收到數(shù)據(jù) : $event');
  });
}
/*
fromIterable 接收到數(shù)據(jù) : 123
fromIterable 接收到數(shù)據(jù) : acb
fromIterable 接收到數(shù)據(jù) : null
fromFuture 接收到數(shù)據(jù) : 2022-09-21 23:01:08.346103
fromFuture onDone
fromFutures 接收到數(shù)據(jù) : 2022-09-21 23:01:08.355317
fromFutures 接收到數(shù)據(jù) : 2022-09-21 23:01:08.355797
fromFutures 接收到數(shù)據(jù) : 2022-09-21 23:01:08.355834
*/

Stream.periodic();

void main(List<String> args) {
  // Stream.periodic(Duration(seconds: 1), (int data) => data).listen((event) {
  //   print('收到數(shù)據(jù):$event'); //收到數(shù)據(jù):null
  // });

  Stream.periodic(Duration(seconds: 1), (int data) => data).take(5) //接收5次數(shù)據(jù)
      .listen((event) {
    print('收到數(shù)據(jù):$event');
  }, onDone: () => print('periodic done'));
  /*
收到數(shù)據(jù):0
收到數(shù)據(jù):1
收到數(shù)據(jù):2
收到數(shù)據(jù):3
收到數(shù)據(jù):4
periodic done
*/
}

11.4 Stream 操作
  • take(int count) | takeWhile() 取count次

  • where()

  • distinct() //去重 去掉和前一個(gè)數(shù)據(jù)相同的數(shù)據(jù)(連續(xù)重復(fù)值)

  • skip(int count) | skipWhile() 跳過count個(gè)

  • map()

  • toSet() | toList() | toString()

  • length | first | last

  • .... 等等

12.Generator(生成器)

概念:生成器是有一種特殊的函數(shù),返回值通過yield 關(guān)鍵詞來指定

分類

  • 同步生成器(sync + yield),yield==return + continue

    • 使用 sync* ,返回是Iterable 對(duì)象
    • yeild 會(huì)返回moveNext為true,并等待moveNext指令
  • 異步生成器(async + yield)

    • 使用 async* ,返回是Stream 對(duì)象
    • yeild不用暫停,數(shù)據(jù)以流的方式一次性推送
  • 遞歸生成器 (yeild*)

    • yeild* 是指針,指向遞歸函數(shù)

    同步生成器(sync + yield)

void main(List<String> args) {
  var nums = getNumber(5).iterator;

  while (nums.moveNext()) {
    print(nums.current);
  }
}

Iterable<int> getNumber(int n) sync* {
  print('start');
  var i = 0;
  while (i < n) {
    yield i++;
  }
  print('end');
/*
start
0
1
2
3
4
end
*/  
}

異步生成器(async + yield)

void main(List<String> args) {
  print('start');
  var stream = getNumbers(5);
  stream.listen((event) {
    print('接收到數(shù)據(jù):$event');
  }, onDone: () {
    print('done');
  });
  print('end');
  /*
start
end
接收到數(shù)據(jù):0
接收到數(shù)據(jù):1
接收到數(shù)據(jù):2
接收到數(shù)據(jù):3
接收到數(shù)據(jù):4
done 
  */
}

Stream<int> getNumbers(int n) async* {
  var i = 0;
  while (i < 5) {
    yield i++;
  }
}

遞歸生成器 (yeild*)

void main(List<String> args) {
  print('start');
  var res = getRange(1, 5);
  res.forEach((element) {
    print(element);
  });
  print('end');
}

Iterable<int> getRange(int start, int end) sync* {
  if (start <= end) {
    yield start;

    // for (var j in getRange(start + 1, end)) {
    //   yield j;
    // } //等價(jià)寫法
    yield* getRange(start + 1, end);
  }
  /*
start
1
2
3
4
5
end  
  */
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容