Dart语法

Dart语法

Dart字符串插入变量

在dart字符串中插入变量

js 复制代码
i = 1
s = f'Hello World{i}'

在python字符串中插入变量

js 复制代码
String stringify(int x, int y) {
  return '$x $y';
}

Dart不支持方法的重载

dart是一种动态的语言,而重载需要机遇静态类型的解析,但是dart支持可以使用命名参数的方式来实现类似于重载的效果

java中的方法重载

js 复制代码
double yearlyIncome(double hourlyRate, double hoursWorkedPerYear)
double yearlyIncome(double monthlyRate, int monthsWorkedPerYear)

dart中使用命名可选参数来实现类似的功能

js 复制代码
void yearlyIncome({double hourlyRate, double monthlyRate, double hoursWorkedPerYear, int monthsWorkedPerYear})

可空变量

?赋值

js 复制代码
int a = null //illegal
int? a = null //legal
int? a // the iniitial value of a is null

避空运算符

js 复制代码
int? a; // = null
a ??= 3;
print(a); // <-- Prints 3.

a ??= 5;
print(a); // <-- Still prints 3.
js 复制代码
print(1 ?? 3); // <-- Prints 1.
print(null ?? 12); // <-- Prints 12.

条件属性访问

js 复制代码
myObject?.someProperty
//等效于
(myObject != null) ? myObject.someProperty : null

箭头语法

js 复制代码
bool hasEmpty = aListOfStrings.any((s) {
  return s.isEmpty;
});
//等效于下列代码
bool hasEmpty = aListOfStrings.any((s) => s.isEmpty);

级联运算符

使用..而不是.的好处是.返回的是表达式的结果而..返回的是表达式运算完的对象的引用,可以在此基础上继续去调用该对象所持有的方法

异常

Dart可以抛出和捕获异常,与java相比,Dart的异常都是unchecked exception。方法不用声明它们可能抛出的异常。也不需要捕获任何异常。使用try, catch, on关键字处理异常。

js 复制代码
try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e');
} catch (e) {
  // No specified type, handles all
  print('Something really unknown: $e');
}

完全无法处理该异常使用rethrow再次抛出

js 复制代码
try {
  breedMoreLlamas();
} catch (e) {
  print('I was just trying to breed llamas!');
  rethrow;
}

抛出异常完毕之后仍然要执行的代码

js 复制代码
try {
  breedMoreLlamas();
} catch (e) {
  // ... handle exception ...
} finally {
  // Always clean up, even if an exception is thrown.
  cleanLlamaStalls();
}

列表构造

js 复制代码
Point.fromJson(Map<String, double> json)
    : x = json['x']!,
      y = json['y']! {
  print('In Point.fromJson(): ($x, $y)');
}

命名构造方法

为了允许一个类具有多个构造方法

js 复制代码
class Point {
  double x, y;

  Point(this.x, this.y);

  Point.origin()
      : x = 0,
        y = 0;
}

工厂构造方法

工厂构造方法能够返回其子类甚至null对象,使用factory关键字进行工厂构造

js 复制代码
class Square extends Shape {}

class Circle extends Shape {}

class Shape {
  Shape();

  factory Shape.fromTypeName(String typeName) {
    if (typeName == 'square') return Square();
    if (typeName == 'circle') return Circle();

    throw ArgumentError('Unrecognized $typeName');
  }
}

函数特性

在dart中,函数可以直接作为变量也可以作为参数传递,函数是一个对象,类型为Function

抽象类

dart定义抽象类

dart中的抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类的借口

js 复制代码
// 定义抽象类  通过abstract关键字类定义
abstract class A{

}

// 抽象类不能被实例化
void main(){
    //  实例化抽象类就报错
    var cat = new A();

}

定义抽象方法

js 复制代码
// 定义抽象方法
abstract class Person{

    // 抽象方法
    // 抽象方法不能使用abstract声明
    // 如果使用就会报错
    void eat();
}

// 不能在非抽象类中定义抽象方法
class Man{
  // 属性
  String name = "小美";
  
  // 方法
  void getInfo(){
    print("我是${name}");
  }
  
  // 抽象方法
  void sayHello();  // 报错

}

抽象类也可以有非抽象方法

js 复制代码
// 定义一个抽象类
abstract class Person{

    // 抽象方法
    eat();

    // 非抽象方法
    printInfo(){
        print("我就是抽象类里的一个非抽象方法");
    }
}

// 子类继承抽象类
class Man extends Person{
    String name;
    Man(this.name){}

    // 子类必须实现抽象类的方法
    @override
    eat() {
        print("${this.name}喜欢吃");
    }
}

// 子类继承抽象类
class Child extends Person{
    String name;
    Child(this.name){}

    // 子类必须实现抽象类的方法
    @override
    eat() {
        print("${this.name}喜欢写代码");
    }
}

void main(){
    Man man = new Man("小美");
    Man.eat();  // 小美喜欢吃

    // 子类调用继承的抽象类中的非抽象方法
    man.printInfo(); 
    
    Child child = new Child("嘟嘟");
    child.eat();  // 嘟嘟喜欢吃
    child.printInfo();  // 我就是抽象类里的一个非抽象方法
}

抽象类的说明

  1. 如果子类继承抽象类必须得实现里面的抽象方法
  2. 如果抽象类被当作接口实现的话,子类必须得实现抽象类里面定义的所有属性和方法
  3. 抽象类不能被实例化,只有继承他的子类可以
  4. 抽象类通常用来定义接口
  5. 抽象类通常具有抽象方法
  6. 有抽象方法的类一定要声明为抽象类

接口

  1. 普通类和抽象类都可以作为接口,类就是接口
  2. 一个普通类要实现某个接口,覆写接口接口类的每个成员
  3. 如果是复用已有类的接口,使用继承
  4. 如果只是使用已有类的外在行为,使用接口
  5. 每个类都隐式的定义了一个包含所有实例成员的接口
js 复制代码
// 抽象类A接口
abstract class A{
    String name;

    // 抽象方法
    printA();
}

// 抽象类B接口
abstract class B{
    int age;

    // 抽象方法
    printB();
}


// Student 类实现 A和B 两个接口
class Student implements A,B{
    // 覆写接口的属性
    @override
    String name;
    int age;
    Student(this.name,this.age);

    // 实现A接口的方法
    @override
    void printA(){
        print("实现A接口的方法");
    }
    // 实现B接口的方法
    @override
    void printB(){
        print("实现B接口的方法");
    }

    // 子类自己的方法
    void sayHello(){
        print("大家好, 我叫${name},今年${age}岁了");
    }
}

// 入口函数
void main(){
    // 实例化子类

    Student xm = new Student("小刚",8);
    xm.printA();   // 实现A接口的方法
    xm.printB();   // 实现B接口的方法
    xm.sayHello();  //大家好, 我叫小刚,今年8岁了

} 

接口和继承的区别

  1. extends是继承,就算有些父类的方法不覆写,子类的实例也能使用父类的方法
  2. implement是实现接口,不管实现多少父类接口,父类里的所有方法都需要覆写

枚举

  1. 使用enum关键字定义一个枚举类型
  2. 枚举是一种有穷序列集的数据类型
  3. 常用于代替常量,控制语句等
  4. 枚举中的每个值都有index,返回索引,索引从0开始
  5. 枚举中的每个值都可以使用values属性列举出来
  • 枚举不能被子类化,混合或实现
  • 枚举不能被显式实例化
js 复制代码
// 定义枚举
enum Color {
    red,
    green,
    blue,
    // 不能指定值,会报错的
    //    whie = "#fff"

}

// 入口函数
void main(){
    // index 获取索引
    print(Color.red.index);  
    print(Color.green.index);
    print(Color.blue.index);

    // value
    print(Color.red);

    // 枚举值
    List list = Color.values;
    print(list); //[Color.red, Color.green, Color.blue]


    // 流程控制
    var color = Color.red;

    switch(color){
        case Color.red:
            print("红色");
            break;
        case Color.green:
            print("绿色");
            break;
        case Color.blue:
            print("蓝色");
            break;
    }
} 

混入

  1. 使用Mixin定义混入类
  2. Minxin类只能继承Object,不能继承其他类
  3. Mixin类似多继承
  4. Mixin类不能声明构造函数,不能调用super
  5. 一个类可以混入多个Mixin类
  6. 使用with关键字进行混入
  7. 在混入多个类时,类中具有相同的属性或方法,后混入的会覆盖数据
  8. 混入不影响继承
js 复制代码
// 使用mixin关键字定义混入类
mixin A{
    String name = "AA";
    printA(){
        print("这是普通类A");
    }
}

mixin B{
    String name = "BB";
    printB(){
        print("这是普通类B");
    }
}

class Student with A,B{

}

// 入口函数
void main(){
    // 实例化子类
    Student student = new Student();
    print(student.name);  // BB
    //在混入多个类时,类中具有相同的属性或方法,后混入的会覆盖数据
    student.printA();     // 这是普通类A
    student.printB();    // 这是普通类B

} 

异步支持

Dart的事件循环

Dart是事件驱动的体系结构,该结构基于具有单个事件循环和两个队列的单线程执行模型。Dart的两个队列分别是MicroTask queue微任务队列和Event queue事件队列

我们可以看出,将任务加入到MicroTask中可以被尽快执行,但也需要注意,当事件循环在处理MicroTask队列时,Event队列会被卡住,应用程序无法处理鼠标单击、I/O消息等等事件。

调度任务

将任务添加到MicroTask队列中

js 复制代码
import  'dart:async';

void  myTask(){
    print("this is my task");
}

void  main() {
    # 1. 使用 scheduleMicrotask 方法添加
    scheduleMicrotask(myTask);

    # 2. 使用Future对象添加
    new  Future.microtask(myTask);
}

将任务添加到Event队列中

js 复制代码
import  'dart:async';

void  myTask(){
    print("this is my task");
}

void  main() {
    new  Future(myTask);
}

延时任务

js 复制代码
new Future.delayed(new Duration(seconds:1),(){ 
    print('task delayed'); 
});

创建Future

  • Future()
  • Future().microtask
  • Future().sync()立刻执行
  • Future().value()
  • Future.delayed()
  • Future().error

注册回调

js 复制代码
import 'dart:async';

void main() {
  print("main start");


  Future fut =new Future.value(18);
  // 使用then注册回调
  fut.then((res){
    print(res);
  });

 // 链式调用,可以跟多个then,注册多个回调
  new Future((){
    print("async task");
  }).then((res){
    print("async task complete");
  }).then((res){
    print("async task after");
  });

  print("main stop");
}

async和await

async关键字作为方法声明的后缀时,具有如下意义

  • 被修饰的方法会将一个Future对象作为返回值
  • 该方法会同步执行其中的方法的代码直到第一个await关键字,然后它暂停该方法其他部分的执行
  • 一旦由await关键字引用的Future任务执行完成,await的下一行代码将立即执行
js 复制代码
// 导入io库,调用sleep函数
import 'dart:io';

// 模拟耗时操作,调用sleep函数睡眠2秒
doTask() async{
  await sleep(const Duration(seconds:2));
  return "Ok";
}

// 定义一个函数用于包装
test() async {
  var r = await doTask();
  print(r);
}

void main(){
  print("main start");
  test();
  print("main end");
}
相关推荐
程序员爱技术1 小时前
Vue 2 + JavaScript + vue-count-to 集成案例
前端·javascript·vue.js
并不会2 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
衣乌安、2 小时前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜2 小时前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师2 小时前
CSS的三个重点
前端·css
耶啵奶膘4 小时前
uniapp-是否删除
linux·前端·uni-app
王哈哈^_^5 小时前
【数据集】【YOLO】【目标检测】交通事故识别数据集 8939 张,YOLO道路事故目标检测实战训练教程!
前端·人工智能·深度学习·yolo·目标检测·计算机视觉·pyqt
cs_dn_Jie6 小时前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic6 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿7 小时前
webWorker基本用法
前端·javascript·vue.js