dart

作者: taoyyyy | 来源:发表于2023-02-16 12:18 被阅读0次

    对于dart的基本认知

    JIT 与 AOT

    Dart 是少数同时支持 JIT(Just In Time,即时编译)和 AOT(Ahead of Time,运行前编译)的语言之一。
    AOT 的典型代表是 C/C++,它们必须在执行前编译成机器码;而 JIT 的代表,则包括了如 JavaScript、Python 等几乎所有的脚本语言。
    但是dart不支持热更新。
    在开发期使用 JIT,开发周期异常短,调试方式颠覆常规(支持有状态的热重载);而发布期使用 AOT,本地代码的执行更高效,代码性能和用户体验也更卓越。

    内存分配与垃圾回收

    Dart VM 的内存分配策略比较简单,创建对象时只需要在堆上移动指针,内存增长始终是线性的,省去了查找可用内存的过程。
    在 Dart 中,并发是通过 Isolate 实现的。Isolate 是类似于线程但不共享内存,独立运行的 worker。这样的机制,就可以让 Dart 实现无锁的快速分配。
    Dart 的垃圾回收,则是采用了多生代算法。新生代在回收内存时采用“半空间”机制。
    Dart 避免了抢占式调度和共享内存,可以在没有锁的情况下进行对象分配和垃圾回收,在性能方面表现相当不错。

    单线程模型

    一旦某个函数开始执行,就将执行到这个函数结束,而不会被其他 Dart 代码打断。所以,Dart 中并没有线程,只有 Isolate(隔离区)。Isolates 之间不会共享内存,就像几个运行在不同进程中的 worker,通过事件循环(Event Looper)在事件队列(Event Queue)上传递消息通信。
    1.I/O、网络请求操作系统提供了异步的API
    2.CPU密集型的操作用Isolate即可

    无需单独的声明式布局语言

    在 Flutter 中,界面布局直接通过 Dart 编码来定义。

    dart语法

    Dart 的变量与类型

    在 Dart 中,我们可以用 var 或者具体的类型来声明一个变量。当使用 var 定义变量时,表示类型是交由编译器推断决定的。
    在默认情况下,未初始化的变量的值都是 null。
    Dart 是类型安全的语言,并且所有类型都是对象类型,都继承自顶层类型 Object,因此一切变量的值都是类的实例(即对象),甚至数字、布尔值、函数和 null 也都是继承自 Object 的对象。

    常量定义

    const,表示变量在编译期间即能确定的值;
    final 则不太一样,用它定义的变量可以在运行时确定值,而一旦确定后就不可再变。

    函数

    函数也是对象,它的类型叫作 Function,可以在函数中传递。

    bool isZero(int number) { //判断整数是否为0
    return number == 0;
    }

    void printInfo(int number,Function check) { //用check函数来判断整数是否为0
    print("number is Zero:{check(number)}");
    }

    Function f = isZero;
    int x = 10;
    int y = 0;
    printInfo(x,f); // 输出 10 is Zero: false
    printInfo(y,f); // 输出 0 is Zero: true

    函数重载

    Dart 认为重载会导致混乱,因此从设计之初就不支持重载,而是提供了可选命名参数和可选参数。具体方式是,在声明函数时:给参数增加{},以 paramName: value 的方式指定调用参数,也就是可选命名参数;给参数增加[],则意味着这些参数是可以忽略的,也就是可选参数。

    tips:可选命名参数是指在调用时需要带上参数名称,如enable1Flags(bold: true, hidden: false);,而可选参数则不用,如enable3Flags(true, false)

    //要达到可选命名参数的用法,那就在定义函数的时候给参数加上 {}
    void enable1Flags({bool bold, bool hidden}) => print("$bold , $hidden");
    
    
    //定义可选命名参数时增加默认值
    void enable2Flags({bool bold = true, bool hidden = false}) => print("$bold ,$hidden");
    
    
    //可忽略的参数在函数定义时用[]符号指定
    void enable3Flags(bool bold, [bool hidden]) => print("$bold ,$hidden");
    
    
    //定义可忽略参数时增加默认值
    void enable4Flags(bool bold, [bool hidden = false]) => print("$bold ,$hidden");
    
    
    //可选命名参数函数调用
    enable1Flags(bold: true, hidden: false); //true, false
    enable1Flags(bold: true); //true, null
    enable2Flags(bold: false); //false, false
    
    
    //可忽略参数函数调用
    enable3Flags(true, false); //true, false
    enable3Flags(true,); //true, null
    enable4Flags(true); //true, false
    enable4Flags(true,true); // true, true
    

    public、protected、private关键字

    Dart 中并没有 public、protected、private 这些关键字,我们只要在声明变量与方法时,在前面加上“”即可作为 private 方法使用。如果不加“”,则默认为 public。不过,“_”的限制范围并不是类访问级别的,而是库访问级别。

    继承与复用

    在 Dart 中,你可以对同一个父类进行继承或接口实现:

    • 继承父类意味着,子类由父类派生,会自动获取父类的成员变量和方法实现,子类可以根据需要覆写构造函数及父类方法;
    • 接口实现则意味着,子类获取到的仅仅是接口的成员变量符号和方法符号,需要重新实现成员变量,以及方法的声明和初始化,否则编译器会报错。
      tips:dart中可以implements一个类。
    class Point {
      num x = 0, y = 0;
      void printInfo() => print('($x,$y)');
    }
    
    
    //Vector继承自Point
    class Vector extends Point{
      num z = 0;
      @override
      void printInfo() => print('($x,$y,$z)'); //覆写了printInfo实现
    }
    
    
    //Coordinate是对Point的接口实现
    class Coordinate implements Point {
      num x = 0, y = 0; //成员变量需要重新声明
      void printInfo() => print('($x,$y)'); //成员函数需要重新声明实现
    }
    
    
    var xxx = Vector();
    xxx
      ..x = 1
      ..y = 2
      ..z = 3; //级联运算符,等同于xxx.x=1; xxx.y=2;xxx.z=3;
    xxx.printInfo(); //输出(1,2,3)
    
    
    var yyy = Coordinate();
    yyy
      ..x = 1
      ..y = 2; //级联运算符,等同于yyy.x=1; yyy.y=2;
    yyy.printInfo(); //输出(1,2)
    print (yyy is Point); //true
    print(yyy is Coordinate); //true
    

    除了继承和接口实现之外,Dart 还提供了另一种机制来实现类的复用,即“混入”(Mixin)。
    tips:混入with本质上是多继承, 当被混入的类有多个同名方法时,调用子类的该方法时,会调用with声明的最后一个拥有该方法的类中的该方法,同时混入中的父类不能继承

    class Point { num x = 0, y = 0; void printInfo() => print('($x,$y)');}
    
    
    class Coordinate with Point {
    }
    
    var yyy = Coordinate();
    print (yyy is Point); //true
    print(yyy is Coordinate); //true
    

    运算符

    • ?. 运算符:假设 Point 类有 printInfo() 方法,p 是 Point 的一个可能为 null 的实例。那么,p 调用成员方法的安全代码,可以简化为 p?.printInfo() ,表示 p 为 null 的时候跳过,避免抛出异常。
    • ??= 运算符:如果 a 为 null,则给 a 赋值 value,否则跳过。这种用默认值兜底的赋值语句在 Dart 中我们可以用 a ??= value 表示。
    • ?? 运算符:如果 a 不为 null,返回 a 的值,否则返回 b。在 Java 或者 C++ 中,我们需要通过三元表达式 (a != null)? a : b 来实现这种情况。而在 Dart 中,这类代码可以简化为 a ?? b。
    • ..级联运算符,在同一个对象上连续调用多个函数以及访问成员变量
    void main() {
      ShoppingCart.withCode(name:'张三', code:'123456')
      ..bookings = [Item('苹果',10.0), Item('鸭梨',20.0)]
      ..printInfo();
    
    
      ShoppingCart(name:'李四')
      ..bookings = [Item('香蕉',15.0), Item('西瓜',40.0)]
      ..printInfo();
    }
    

    运算符重载

    class Vector {
      num x, y;
      Vector(this.x, this.y);
      // 自定义相加运算符,实现向量相加
      Vector operator +(Vector v) =>  Vector(x + v.x, y + v.y);
      // 覆写相等运算符,判断向量相等
      bool operator == (dynamic v) => x == v.x && y == v.y;
    }
    
    
    final x = Vector(3, 3);
    final y = Vector(2, 2);
    final z = Vector(1, 1);
    print(x == (y + z)); //  输出true
    

    相关文章

      网友评论

          本文标题:dart

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