美文网首页
dart 语法进阶

dart 语法进阶

作者: 朱允见 | 来源:发表于2022-09-23 15:10 被阅读0次

    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 提高代码的复用度

    • class mixin 关键字都可已推荐 mixin
    • with 可以是多个 ”,“ 分割,后面的属性和方法重名会覆盖前面的
    • 用作混入的类不能有构造函数
    • mixin 类只能继承 Object
    //  class  mixin
    class MixinA {
      String name = 'MixinA';
      void showInfo() {
        print(name);
      }
    }
    
    mixin MixinB {
      // MixinB(); 用作混入的类不能有构造函数
      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 扩展

    //扩展内置类
    extension StringExt on String {
      int parseInt() {
        return int.parse(this);
      }
    }
    
    //扩展自定义类
    class Person {
      final String name;
      Person(this.name);
    }
    
    extension PersonExt on Person {
      info() {
        print(this.name);
      }
    }
    

    4. call

    • 在类中可以声明call 方法

    • 类的实例当做行数使用

      void main(List<String> args) {
        var phone = Phone();//将类的实例当做函数使用
        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 对象的唯一标识
    • 表现为一串数字 // eg: obj.hashCode; 608635269
    • 可以判断两个对象是否是同一个内存地址

    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 事件轮询机制

    image.png image.png

    9 isolate

    • isolate 是dart 中的线程
      • 每个isolate都有自己的独立的私有内存(多个isolate不共享内存)
      • dart中的线程是以 隔离(isolate)的方式存在
      • 没有共享没存,不存在资源竞争(不需要锁,也就没有死锁)
    • 所有dart 都运行在isolate中
      • isolate 提供了dart | flutter 的运行环境
      • 微任务队列、事件队列、事件轮询 都在isolate 中进行
    • 多线程长用来解决耗时较长的异步任务
    • isolate的位置
    image.png
    9.1 isolate 多线程-创建
    • Isolate 类 用来管理线程(创建、暂停、杀死 Isolate线程)

      Isolate.spawn();//创建线程
      Isolate.spawnUri();//跨文件 函数创建线程
      Isolate.pause();//暂停
      Isolate.kill();//杀死
      
    import 'dart:isolate';
    /*
    entryPoint : 必须是一个顶层方法或静态方法
    message:
      1. dart 原始类型 eg:null,int,String ...
      2. SendPort 实例 ReceivePort().sendPort 
      3. 包含 1 和 2 的list、 map 可以嵌套
    
    */
    static Future<Isolate> spawn<T>(void entryPoint(T message), T message);
    
     
    import 'package:flutter/foundation.dart'
    compute();
    
    • 使用实例1:创建一个线程

      import 'dart:isolate';   
      void main() {
        test();
      }
      void test() async {
        print('---start---');
        print('thead: ${Isolate.current.debugName}');
        Isolate.spawn(newThread1, 'zhu'); //一般 异步执行  
        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');
      }
      
    • 实例2 创建多个线程

      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 多线程通信机制-Port
    • isolate 多线程之间通信的唯一方式是 Port

    • ReceivePort 类,初始化接受端口,创建发送端口,接受消息、监听消息、关闭端口

    • SendPort 类 将消息发送给ReceivePort

    • 通信方式

      • 单项通信:A -> B
      • 双向通信:A <-> B
      • image.png
    import 'dart:isolate';
    
    void main(List<String> args) {
      test();
    }
    
    test() {
      print('---start---');
      print(Isolate.current.debugName);
      //创建接收端口
      ReceivePort receivePort = ReceivePort();
      //建立监听
      receivePort.listen((message) {
        print('listen: $message');
    
        //关闭监听
        receivePort.close();
      });
    
      //获取发送端口
      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 发来的消息');
    }
    
    image.png
    import 'dart:isolate';
    
    void main(List<String> args) async {
      print('---start---');
      print(Isolate.current.debugName);
      //创建接收端口
      ReceivePort r1 = ReceivePort();
      //建立监听
    
      //获取发送端口
      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} 发送消息: $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];
    
        //回复消息
        replyPort.send('子线程答复->$data');
      }
    }
    /*
     ---start---
    main
    main 发送消息: hello
    新线程收到了主线程的消息:hello
    主线程接收到:子线程答复->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 实例封装一些异步任务

      • Future 含义是未来。未来要执行的任务可以放到Future中

    • Future 的三种状态

      • 未完成 (Uncompleted)
      • 已完成,并返回数据(Complete with data)
      • 已完成,但返回错误(Complete with error)
    • 获取实例

      • 自动返回

        • final myFuture = http.get('http://xxxx')
        • final myFuture = SharePreferences.getInstace;
      • 手动创建

        • final myFuture = Future((){return 123;});
        • final myFuture = Future.error(Exception());
        • Final myFuture = Future.delayed(Duration(seconds:3),(){return 123;});
    • 状态相关方法

      • 创建
        • 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 '异常数据';
      });
    
      myFuture.then((value) => print(value)).catchError((error) {
        print('error : ' + error);
      }, test: (error) => error.runtimeType == String).whenComplete(
          () => print('complate'));
      print('end');
    }
    /*
    start
    end
    error : 异常数据
    complate
    */
    
    10.2 Future执行顺序
    • Future 默认是异步任务,会被丢到事件队列(event queue)中

    • Future.sync()

      • 同步任务,同步执行(不会丢到异步队列)
    • Future.microtast()

      • 微任务丢到microtask queue 中优先级比event queue 高
    • Future.value(val)

      • val 是常量 (等同microtask)

      • val 是异步(按照异步任务处理)

    10.3 多任务
    • Future.any(Futures) 返回最先完成的Future结果

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

    • Future.doWhile(action) 按照条件遍历执行多个Future

    • Future.forEach(elements,action) 遍历一个给定的集合,根据集合元素执行多个Future

    10.4. FutureBuilder - snapshot
    1. snapshot.connectionState
    • ConnectionState.none (未连接异步任务)
    • ConnectionState.waiting (连接异步任务,等待交互)
    • ConnectionState.active (连接异步任务,正在交互)
    • ConnectionState.done (异步任务完成)
    1. snapshot.hasData

    2. snapshot.hasError

    11.Stream

    11.1 Stream 概念

    Stream 是Dart 中异步数据流,可以连续不断地返回多个数据。

    • Future是异步 ,单只返回一个值
    • Stream也是异步,可以返回多个值(数据流)

    Stream 相关的API

    • 通过listen进行数据监听
    • 通过error 接受失败状态
    • done来接收结束状态
    11.2 Stream 类型

    Single-Subscription (单一订阅)

    • 数据流只能listen 一次(listen 多次会报错)
    • StreamController().stream
    • Stream stream = Stream.fromIterable(data)
    import 'dart:async';
    
    void main(List<String> args) {
      //创建一次订阅数据流控制器
      StreamController streamController = StreamController();
    
      //一次监听 只能监听一次
      streamController.stream.listen((event) {
        print('接收到数据:$event');
      });
    
      //sink数据槽 添加数据
      streamController.sink.add('123');
      streamController.sink.add('abc');
      /*
    接收到数据:123
    接收到数据:abc
      */
    }
    
    

    Broadcase (广播)

    • 数据流可以被 listen 多次
    • StreamController<int>.broadcast();
    • stream.asBroadcastStream()
    import 'dart:async';
    
    void main(List<String> args) {
      //创建多次订阅数据流控制器
      StreamController streamController = StreamController.broadcast();
    
      streamController.stream.listen((event) {
        print('第一次监听接收到数据:$event');
      });
    
      //sink数据槽 添加数据
      streamController.sink.add('123');
    
      streamController.stream.listen((event) {
        print('第二次监听接收到数据:$event');
      });
      streamController.sink.add('abc');
    
    /*
    第一次监听接收到数据:123
    第二次监听接收到数据:abc
    第一次监听接收到数据:abc
    */
    }
    
    
    11.3 创建 Stream 实例

    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 接收到数据 : $event');
      }, onDone: () {
        print('fromFuture onDone');
      });
    
      Stream.fromFutures([getFuture(), getFuture(), getFuture()]).listen((event) {
        print('fromFutures 接收到数据 : $event');
      });
    
      Stream.fromIterable([123, 'acb', null]).listen((event) {
        print('fromIterable 接收到数据 : $event');
      });
    }
    /*
    fromIterable 接收到数据 : 123
    fromIterable 接收到数据 : acb
    fromIterable 接收到数据 : null
    fromFuture 接收到数据 : 2022-09-21 23:01:08.346103
    fromFuture onDone
    fromFutures 接收到数据 : 2022-09-21 23:01:08.355317
    fromFutures 接收到数据 : 2022-09-21 23:01:08.355797
    fromFutures 接收到数据 : 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('收到数据:$event'); //收到数据:null
      // });
    
      Stream.periodic(Duration(seconds: 1), (int data) => data).take(5) //接收5次数据
          .listen((event) {
        print('收到数据:$event');
      }, onDone: () => print('periodic done'));
      /*
    收到数据:0
    收到数据:1
    收到数据:2
    收到数据:3
    收到数据:4
    periodic done
    */
    }
    
    
    11.4 Stream 操作
    • take(int count) | takeWhile() 取count次

    • where()

    • distinct() //去重 去掉和前一个数据相同的数据(连续重复值)

    • skip(int count) | skipWhile() 跳过count个

    • map()

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

    • length | first | last

    • .... 等等

    12.Generator(生成器)

    概念:生成器是有一种特殊的函数,返回值通过yield 关键词来指定

    分类

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

      • 使用 sync* ,返回是Iterable 对象
      • yeild 会返回moveNext为true,并等待moveNext指令
    • 异步生成器(async + yield)

      • 使用 async* ,返回是Stream 对象
      • yeild不用暂停,数据以流的方式一次性推送
    • 递归生成器 (yeild*)

      • yeild* 是指针,指向递归函数

      同步生成器(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('接收到数据:$event');
      }, onDone: () {
        print('done');
      });
      print('end');
      /*
    start
    end
    接收到数据:0
    接收到数据:1
    接收到数据:2
    接收到数据:3
    接收到数据: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;
        // } //等价写法
        yield* getRange(start + 1, end);
      }
      /*
    start
    1
    2
    3
    4
    5
    end  
      */
    }
    
    

    相关文章

      网友评论

          本文标题:dart 语法进阶

          本文链接:https://www.haomeiwen.com/subject/zhsnortx.html