dart其他语法

dart其他语法

https://www.wenjiangs.com/doc/4rjgb53a

类型相关

空安全

不能将一个普通类型对象赋值为 null

  • 避免 为空 报错:对 null 的使用语法进行限制(str != null)
  • 对空安全的允诺

late 延迟初始化的时机
! 在此时该可用变量一定不为空

void main() {
  String name = 'zhang';
  say(name);
  String? xm = null; // 可空的字符串
  try {
    say(xm!); // ! 在此时该可用变量一定不为空
  } catch (e) {
    print(e);
  }
}

void say(String str) {
  late String name; // 承诺 name 不为空,先定义
  if (str == null) {
    throw Exception('Invalid string');
  }
  print('my name: $str ,has ${str.length} characters');
}

类定义相关语法

  • 类的运算符重载

就是个参数固定,名称特殊的函数而已。

class Vec2 {
  double x, y;
  Vec2(this.x, this.y);
  // operator 关键字加上 运算符 作为方法名即可
  // 加法是二元运算符,所以方法中有一个入参。该入参类型就是使用时 + 后面的对象类型
  // 开头 Vec2 依然表示返回类型
  Vec2 operator +(Vec2 other) => Vec2(x + other.x, y + other.y);
  // 接收一个 入参是布尔值的列表,返回一个浮点数
  double operator [](bool flag) => flag ? x : y;
  
  String toString() {
    return 'Vec2(x: $x, y: $y)';
  }
}

void main() {
  Vec2 v1 = Vec2(1, 2);
  Vec2 v2 = Vec2(3, 4);
  double val = v1[true];
  print((v1 + v2).toString());
  print(val);
}
  • 类的扩展方法

支持在某类定义文件之外,拓展该类的方法,在其中可以访问类成员
相当于 js 在原型上添加方法
extension A on B 来定义,其中 A 的名字是任意的,B 是拓展的目标类
不能在拓展在原类中已存在的方法

// A相当于 string的一个成员方法,可以访问this对象
extension A on String {
  String isANullString() {
    // ignore: unnecessary_this
    if (this.trim() == '') {
      return 'yes';
    } else {
      return 'no';
    }
  }
  bool isPhone() {
    RegExp regExp = RegExp(r'^1[34578]\d{9}$');
    return regExp.hasMatch(this);
  }
  // 运算符本身也是一种方法,支持扩展
  // 判断配个 String 首位字符的大小
  bool operator >(String other) {
    int thisCode = 0;
    int otherCode = 0;
    if (isNotEmpty) {
      // 相当于this.
      thisCode = codeUnits.first; // 相当于this.
      print(thisCode);
    }
    if (other.isNotEmpty) {
      otherCode = other.codeUnits.first;
      print(otherCode);
    }
    return thisCode > otherCode;
  }
}
void main() {
  String str = '     ';
  String res = str.isANullString();
  print(res);
  String str1 = '13550256060a';
  bool res1 = str1.isPhone();
  print(res1);
  String str2 = 'hello';
  String str3 = 'nihao';
  bool res2 = str2 > str3;
  print(res2);
}
  • 几个符号介绍

… 可以实现连续的调用
… 用于解构可迭代对象

class Person {
  String name = '';
  int age = 0;

  void log() {
    print("name:$name,age:$age");
  }
}

void main() {
  Person toly = Person();
  // toly.name = "toly";
  // toly.age = 28;
  // toly.log();
  // .. 可以实现连续的调用,等价于上面三行,语法糖而已
  toly
    ..name = "toly"
    ..age = 28
    ..log();
  // ... 用于解构可迭代对象
  List list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
  List list2 = [0, ...list, 100];
  print(list2);
}
  • enum 枚举
enum GenderType { male, female, secrecy }
String ShowInfoByGender(GenderType type) {
  switch (type) {
    case GenderType.male:
      return "男性";
    case GenderType.female:
      return "女性";
    case GenderType.secrecy:
      return "保密";
  }
}
void main() {
  GenderType type = GenderType.male;
  // List<GenderType> li = GenderType.values;
  // print(li); // [GenderType.male, GenderType.female, GenderType.secrecy]
  String res = ShowInfoByGender(type);
  print(res);
}

函数类型的回调与监听

通过 typedef 来定义一个函数类型

typedef OperateNumFun = int Function(int num1, int num2);
void main() {
  // addNumFun 是 OperateNumFun 函数类型
  OperateNumFun addNumFun = (num1, num2) {
    return num1 + num2;
  };
  OperateNumFun plusNumFun = (num1, num2) {
    return num1 * num2;
  };
  print(addNumFun(1, 2));
  print(plusNumFun(1, 2));
  print(plusNumFun.runtimeType); // (int, int) => int
}
  • 高级用法
typedef OnBiteCallBack = void Function(String name);
// 函数作为参数传入到类的构造函数中
// 通过回调与监听,可以为不同类之间 事件触发 和 数据传递 提供一种机制
class FishMan {
  final OnBiteCallBack hook;

  FishMan({required this.hook});
}
class Pond {
  FishMan fishMan;
  Pond({required this.fishMan});

  void emitFish(String name) {
    fishMan.hook(name);
  }
}
main() {
  FishMan man = FishMan(hook: (String name) {
    print("钓到一条$name");
  });
  Pond pond = Pond(fishMan: man);
  pond.emitFish("鲫鱼");
}

语法相关

异步中的 Future 对象

  • 异步任务与回调
// Future 中有一个 then 方法,用于监听异步任务的完成
// 通过 async 声明异步,await等待 Future对象执行完成
import "dart:io";
import "package:path/path.dart" as path;

void main() async {
  File file = File(path.join(Directory.current.path, "../one.iml"));
  // file.readAsString().then((value) => print(value));
  String value = await file.readAsString();
  print(value);
}
  • Stream 对象

Future 对象是一件异步任务,那么 Stream 则是一系列的异步任务
它可以监听到若干次回调

// stream(params1,params2)
// params1 :每次读取到数据,都会触发 params1 方法
// params2 用于监听读取完毕的事件
// Stream#listen 方法会返回一个 StreamSubscription 的订阅对象
// subscription.cancel 方法取消监听
// subscription.pause(); 暂停监听
// subscription.resume(); 恢复监听
import 'dart:io';
import "package:path/path.dart" as path;

class ReadFile {
  int fileLength = 0;
  int count = 0;
  late dynamic subscription;
  void taskOne() async {
    File file = File(path.join(Directory.current.path, '../web/index.html'));
    fileLength = await file.length();
    print('开始读取文件');
    Stream<List<int>> stream = file.openRead();
    subscription = stream.listen(taskTwo, onDone: complete);
  }

  void taskTwo(List<int> bytes) {
    count += bytes.length;
    double percentage = count * 100 / fileLength;
    DateTime time = DateTime.now();
    String timestr =
        '${time.hour}:${time.minute}:${time.second}:${time.microsecond}';
    print('当前进度:' +
        timestr +
        "=" * (percentage ~/ 2) +
        '${percentage.toStringAsFixed(2)}%');
    if (percentage < 50) {
      subscription.cancel();
    }
  }

  void complete() {
    print('读取完毕');
  }
}

void main() {
  var task = new ReadFile();
  task.taskOne();
}

文件管理

  • 文件内容的显隐: show 与 hide

被引用文件,如果建立私有方法或者变量,下划线开头,外部即访问不到
如果 定义被引用文件可访问的变量 方法,可使用 show和hide约定

// a.dart
void say(String str) {
  print('this is ' + str);
}

double age = 20;
String name = '张山';
String hobby = 'read 、sing';
String _address = '武汉市xxxx';
void _hello(String str) {
  print('hello ' + str);
}
// import './h.dart' as helpers hide hobby; // 基文件 中变量hobby无法访问
import './a.dart' as helpers show name, say, age; // 允许访问 name, say, age
void main() {
  helpers.say('你好');
  // helpers._hello('你好');  基文件下划线开头的方法无法访问
  print(helpers.age);
  // print(helpers._address);  基文件下划线变量无法访问
  // print(helpers.hobby); 报错
  print(helpers.name);
}
  • 部分与整体: part of 与 part

通过 part 关键字表示指定文件是当前文件的一部分。另外在部分的文件中使用 part of 关键字表示归属关系

// 宿主文件 g.dart
import 'dart:io'; // 给寄生文件用
part './h.dart'; // 表示 h.dart是当前文件一部分
void main() {
  say('你好');
  print('$_address'); // $_访问 私有方法 变量
  print(_address); // 直接访问
  print(name);
  _hello('你好');
}
// h.dart
// 只能在宿主文件中 import引入 当前需要的第三方文件库
part of './g.dart'; // 表示当前文件是 g.dart 文件一部分
void say(String str) {
  print('this is ' + str);
  print('当前路径是:${Directory.current.path}/g.dart');
}
double age = 20;
String name = '张山';
String hobby = 'read 、sing';
String _address = '武汉市xxxx';
void _hello(String str) {
  print('hello ' + str);
}
  • 定义库与导出: library 与 export

使用 library 关键字定义库名,export 关键字导出相关文件

// m.dart
void logTime() {
  var time = DateTime.now();
  String str = '${time.hour}:${time.minute}:${time.second}';
  print(str);
}
// h.dart
import 'dart:io';
void say(String str) {
  print('当前路径是:${Directory.current.path}/g.dart');
}
// helper_lib.dart
export './m.dart';
export './h.dart';
import 'helper_lib.dart' as Helper;
void main() {
  Helper.logTime();
  Helper.say('string');
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值