dart 语法进阶

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 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 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 (dart:2.13之后)
typedef MathOperation = Function(int a, int b);
fn1(int a, b) {
  return a + b;
}
void main(List 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 spawn(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 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 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 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 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 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 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 args) {
  //创建一次订阅数据流控制器
  StreamController streamController = StreamController();

  //一次监听 只能监听一次
  streamController.stream.listen((event) {
    print('接收到数据:$event');
  });

  //sink数据槽 添加数据
  streamController.sink.add('123');
  streamController.sink.add('abc');
  /*
接收到数据:123
接收到数据:abc
  */
}

Broadcase (广播)

  • 数据流可以被 listen 多次
  • StreamController.broadcast();
  • stream.asBroadcastStream()
import 'dart:async';

void main(List 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 getFuture() async {
  await Future.delayed(Duration(seconds: 2), () {});
  return DateTime.now().toString();
}

void main(List 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 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 args) {
  var nums = getNumber(5).iterator;

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

Iterable 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 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 getNumbers(int n) async* {
  var i = 0;
  while (i < 5) {
    yield i++;
  }
}

递归生成器 (yeild*)

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

Iterable 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 语法进阶)