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");
}
相关推荐
BBB努力学习程序设计5 分钟前
CSS3渐变:用代码描绘色彩的流动之美
前端·html
冰暮流星15 分钟前
css之动画
前端·css
jump68039 分钟前
axios
前端
spionbo42 分钟前
前端解构赋值避坑指南基础到高阶深度解析技巧
前端
用户4099322502121 小时前
Vue响应式声明的API差异、底层原理与常见陷阱你都搞懂了吗
前端·ai编程·trae
开发者小天1 小时前
React中的componentWillUnmount 使用
前端·javascript·vue.js·react.js
永远的个初学者1 小时前
图片优化 上传图片压缩 npm包支持vue(react)框架开源插件 支持在线与本地
前端·vue.js·react.js
爱吃土豆的马铃薯ㅤㅤㅤㅤㅤㅤㅤㅤㅤ1 小时前
npm i / npm install 卡死不动解决方法
前端·npm·node.js
Kratzdisteln1 小时前
【Cursor _RubicsCube Diary 1】Node.js;npm;Vite
前端·npm·node.js
杰克尼2 小时前
vue_day04
前端·javascript·vue.js