美文网首页
Dart常用功能语法——只记录和OC、Swift不同的地方

Dart常用功能语法——只记录和OC、Swift不同的地方

作者: IMKel | 来源:发表于2021-11-15 18:17 被阅读0次
    • 打印变量
      打印变量:$变量名
      打印表达式: ${表达式}
    void main() {
      //输出变量
      String name = '张三';
      num age = 12;
      num height = 1.77;
    
      print('我叫$name, 出生于${DateTime.now().year - age}, 身高$height');//打印 我叫张三, 出生于2009, 身高1.77
    }
    
    • 一些重要概念(要记在脑子里)
      1.可以放在变量中的所有东西,都是对象,都是类的实例。都继承Object类。
      2.强类型语言。支持类型推断,故可省略变量的类型。
      3.空安全。默认变量不可为null,否则需要在类型后面加上问号?,表示该变量可以为null。
      4.When you want to explicitly say that any type is allowed, use the type Object? (if you’ve enabled null safety), Object, or — if you must defer type checking until runtime — the special type dynamic.(还没理解透)
      5.支持泛型类型
      6.支持顶级函数。即可在类以为定义函数,或函数内定义函数。
      7.Similarly, Dart supports top-level variables, as well as variables tied to a class or object (static and instance variables). Instance variables are sometimes known as fields or properties.(这好像没啥好说的)
      8.和Java不同,dart没有public, protected, 和 private这类修饰词,如果标识符以下划线开头,那么该标识符对应的标量就是私有的。
      9.Identifiers can start with a letter or underscore (_), followed by any combination of those characters plus digits.(没啥好说的)

    • 变量

    void main() {
      //1.变量默认值
      //可空变量的默认值是null
      num? age;
      if (age == null) {
        print('年龄为空'); //打印  年龄为空
      }
      //不可为空的变量默认值需要手动去初始化
      num height = 1.77;
      print('身高$height'); //打印 身高1.77
    
      //2.late变量(多用于类成员属性的初始化),使用这个关键字意味着
      //2.1声明一个非空的变量
      //2.2延迟初始化变量
      late String name;
      name = '赵六';
      print(name); //打印 赵六
    
      //3.final和const,被这两个关键字修饰的变量不可以修改。const是隐式的final
      //注意:实例变量可以用final修饰,不可以用const
      final Persion p;
      // const Persion p2;//会报错
    
      //使用区别:
      //3.1 final:多用于定义不可修改的常量
      //3.2 const:多用于隐式定义不可修改的常量,例如:给flutter组件的child属性赋值时,可以使用const
    }
    
    • 基本数据类型
      //int类型
      int age = 28;
      print(age);
      
      //double类型
      double height = 1.88;
      print(height);
      
      //字符串
      String name = 'bob';
      print(name);
      
      //常量
      final double pi = 3.14;
      print(pi);
    //   pi = 3.141596;//修改会报错,因为final定义的变量是不可修改的
      
      const double pi2 = 3.14;
      print(pi2);
    //   pi2 = 3.141596;//修改会报错,因为const定义的变量是不可修改的
    
    //num类型,int和double都是num类型
      num numberValue = 3;
      print(numberValue);
      numberValue = 3.1;
      print(numberValue);
      
      //布尔类型
      bool enable = 1==1;
      print(enable);
      
      //list类型,也即是array。
      List chars = ['a','b','c'];
      print(chars);
      print(chars.length);
      print(chars[0]);
      
      //set类型
      Set student_no = {'1001','1002','1003'};
      print(student_no);
      student_no.add('1004');
      print(student_no.length);
    
      //map类型
      Map letters = {'A':'a', 'B':'b'};
      print(letters);
      letters['C'] = 'c';
      print(letters.length);
      print(letters['C']);
    
    • 类型转换
      final double pi = 3.14;
      var pi_str = pi.toString();
      print('str = '+pi_str);
      
      var pi_double = double.parse('3.1415926');
      print(pi_double);
    
    • 函数
      //Function类型。dart中,函数也是对象
      sayHello(){
        print('hello dart');
      }
      sayHello();
      
      //函数的箭头语法(当方法体中只有一个 表达式 时,可以使用箭头语法)
      String greet(String name) => 'hello '+name;
      print (greet('Bob'));
      
      //命名可选参数{}
      void printUser(String name, {int age = 0}){
        print('name='+name+', age='+age.toString());
      }
      printUser('Jhon', age:10);
      
      //可选参数[]
      void printUser2(String name, [double height = 0.0]){
        print('name='+name+', height='+height.toString());
      }
      printUser2('Tony');
      printUser2('Tony', 1.70);
      
      //匿名函数(有时候也被称为 lambda 或者 closure )
      //定义:([[TYPE] param1[,...]]) {codeBlock}
      var list = ['apples', 'bananas', 'oranges'];
      list.forEach((item){
        print('${list.indexOf(item)}: $item');
      });
      //或者使用箭头语法
      list.forEach((item) => print('${list.indexOf(item)}: $item')); 
    }
    
    • 运算符
    void main() {
      //算数运算符 ~/
      print(5 ~/ 2); //打印2
    
      //类型判定运算符 as is is!
      //as:强制类型转换
      dynamic persion = Persion();
      // children.name = '张三';//会报错
      (persion as Persion).name = '张三';
      print(persion.name); //打印张三
    
      dynamic persion2 = Persion();
      Persion p = persion2 as Persion;
      p.name = '小明';
      print(p.name); //打印 小明
    
      //is:类型判断,是xxx的意思
      if (persion is Persion) {
        print('是个人'); //打印 是个人
      }
    
      //is!:is的取反,不是xxx的意思
      if (persion is! Robot) {
        print('人可不是机器人'); // 打印 人可不是机器人
      }
    
      //赋值运算符 ??= :只有当左边的变量为null时,才会将右边的值赋值给变量
      var value1;
      value1 ??= 2;
      print(value1); // 打印 2
    
      var value2 = 1;
      value2 ??= 2;
      print(value2); //打印 1
    
      //级联运算符 .. :实现对同一个对像进行一系列的操作
      var persion3 = Persion()
        ..name = '李四'
        ..age = 12
        ..height = 1.77;
      print(persion3.name! +
          ' ' +
          persion3.age.toString() +
          ' ' +
          persion3.height.toString()); //打印 李四 12 1.77
    }
    
    class Persion {
      String? name;
      double? height;
      int? age;
    }
    
    class Robot {}
    
    
    • 控制流程语句
    void main() {
      //iterable接口对控制流程的增强
      //dart中的集合默认都实现了iterable接口
      var candidate = [
        Persion(name: '张三', age: 12),
        Persion(name: '李四', age: 18),
        Persion(name: '王五', age: 20)
      ];
      candidate.forEach((element) {
        print(element.name! +
            '---' +
            element.age.toString()); // 打印出 张三---12  李四---18 王五---20
      });
    
      //实现iterable接口,还可以做过滤操作
      candidate.where((element) => element.age! >= 18).forEach((element) {
        print(
            element.name! + '---' + element.age.toString()); // 打印出 李四---18 王五---20
      });
    
      //断言语句:assert 语句只在开发环境中有效, 在生产环境是无效的
      assert(1 > 2, '断言成功,下面的语句将不会执行');
      print('我被执行了');
    }
    
    class Persion {
      String? name;
      double? height;
      int? age;
    
      Persion({this.name, this.height, this.age});
    }
    
    void main() {
      //类
      //使用特殊点语法:?. 可以避免左边对象可能为 null , 导致的异常
      var p = Person();
      print(p.house?.address); //打印 null,如果将?.换成. 那么运行就会报错
    
      //dart中的类和swift中一样,属性都需要在实例化的时候赋值,例如Point类
      var point1 = Point(3, 5);
      print(point1); //打印 Instance of 'Point'
      var point2 = Point.fromJson({'x': 2, '7': 8});
      print(point2); //打印 Instance of 'Point'
    
      //和其他不一样,dart有常量构造体,例如:
      var immutablePoint1 = ImmutablePoint.point;
      // immutablePoint1.x = 10;//修改就会报错
      var immutablePoint2 = ImmutablePoint.point;
      // immutablePoint2.x = 15;//修改同样会报错
    
      //获取对象的类型
      print('p对象的类型是:${p.runtimeType}'); //打印 p对象的类型是:Person
    
      //类final成员属性的赋值方式。且实例创建之后无法修改name属性
      //第一种方式
      var mark = ProfileMark('张三');
      print(mark.name); //打印 张三
      //第二种方式
      mark = ProfileMark.unname();
      print(mark.name); //打印 还没设置名字哦
    
      //dart语言特有的构造器——名字构造器
      var nameConstructorPoint = Point.origin();
      print(nameConstructorPoint); //打印  Instance of 'Point'
    
    //如果父类没有名字构造器或无参构造器,那么子类就必须手动去调用父类的一个构造器,通过在
    //构造器函数体后面加上冒号,再紧接父类构造函数体
      var e = Employee.fromJson({});
      print(e);
      //构造对象e的过程先后打印
      //in person
      //in employee
      //Instance of 'Employee'
    
      //类中定义运算符——dart语言又一牛逼操作
      var vector1 = Vector(1, 1);
      var vector2 = Vector(2, 2);
      var sumVector = vector1 + vector2;
      print('sumVector.x = ${sumVector.x}, sumVector.y = ${sumVector.y}');
      //打印  sumVector.x = 3, sumVector.y = 3
    
      //get set关键字——可通过get set 创建额外的属性
      var rectangle = Rectangle(1, 1, 10, 10);
      print('rectangle.right = ${rectangle.right}'); //打印 rectangle.right = 11.0
      rectangle.right = 20;
      print('rectangle.left = ${rectangle.left}'); //打印 rectangle.right = 10.0
    
      //dart又一重磅功能——类使用混合(mixin),用于类多层继承关系中,类代码重用的一种方法
      //查看这几个类或mixin:Performer,Musical,Musician,Maestro。了解混合的意思。
      //关键词:with,on
      //with:类的后面跟随with,然后跟上定义的Mixin,例如:class ClassA with MixinA {}
      var maestro = Maestro('小明');
      print(maestro.canPlayPiano); //打印  false
      print(maestro.canConduct); //打印  true
      print(maestro.canCompose); //打印  false
    
      //on:用于限制Mixin的使用范围,例如:Mixin MixinA on ClassA {}
      //如果ClassB不继承ClassA,而是直接 with MixinA时,编译时期
      //就会报错,更别说使用cb调用printSomething方法了。
      var cb = ClassB();
      cb.printSomething(); //打印  ---printSomething---
    }
    
    class Person {
      String? name;
      double? height;
      int? age;
      House? house;
    
      Person({this.name, this.height, this.age, this.house});
    
      Person.fromJson(Map json) {
        print('in person');
      }
    }
    
    class Employee extends Person {
      //父类没有名称构造器和无参构造器时,需要手动调用父类的构造器
      Employee.fromJson(Map json) : super.fromJson(json) {
        print('in employee');
      }
    }
    
    class Point {
      num x = 0.0;
      num y = 0.0;
      //定义构造器的两种写法
      Point(this.x, this.y); //简写方式
    
      //标准写法
      // Point(num x, num y) {
      //   this.x = x;
      //   this.y =
      // }
    
      //工厂构造函数——并不总会构造新对象,可能从缓存返回实例,也可能返回子类型实例。
      factory Point.fromJson(Map<String, num> json) {
        return Point(json['x'] ?? 0, json['y'] ?? 0);
      }
    
      //名字构造器
      Point.origin()
          : x = 0,
            y = 0;
    }
    
    //不可变Point
    class ImmutablePoint {
      static const ImmutablePoint point = ImmutablePoint(0, 0);
      final num x, y;
      const ImmutablePoint(this.x, this.y);
    }
    
    class House {
      String address;
      House({required this.address});
    }
    
    class ProfileMark {
      final String name;
    
      ProfileMark(this.name);
      //这也是一种构造方式
      ProfileMark.unname() : name = '还没设置名字哦';
    }
    
    class Vector {
      final int x, y;
    
      Vector(this.x, this.y); //定义构造函数
      //操作符返回类型 操作符关键字 操作符标识符
      Vector operator +(Vector v) => Vector(x + v.x, y + v.y);
      Vector operator -(Vector v) => Vector(x - v.x, y - v.y);
    }
    
    class Rectangle {
      double left, top, width, height;
    
      Rectangle(this.left, this.top, this.width, this.height);
    
      //返回值类型 关键字 属性名 => 返回值计算
      double get right => left + width;
      //无返回值 关键字 属性名 参数列表 => 设置属性逻辑
      set right(double value) => left = value - width;
    
      double get bottom => top + height;
      set(double value) => top = value - height;
    }
    
    //表演家
    class Performer {}
    
    //音乐的
    mixin Musical {
      bool canPlayPiano = false; //会弹钢琴
      bool canCompose = false; //会创作、作曲
      bool canConduct = false; //会指挥
    
      //招待我
      void entertainMe() {
        if (canPlayPiano) {
          print('弹钢琴');
        } else if (canConduct) {
          print('指挥');
        } else {
          print('自言自语');
        }
      }
    }
    
    //音乐家
    class Musician extends Performer with Musical {}
    
    //大师
    class Maestro extends Person with Musical {
      Maestro(String maestroName) {
        name = maestroName;
        canConduct = true;
      }
    }
    
    //Mixin中限制关键词on的使用
    class ClassA {}
    
    mixin MixinA on ClassA {
      printSomething() {
        print('---printSomething---');
      }
    }
    
    class ClassB extends ClassA with MixinA {}
    
    • 库和库的可视性
    void main() {
      //库和可视性
      //1.导入内置库格式:impot 'dart: scheme'; //其中scheme表示格式、结构
    
      //2.倒入第三方库
      //2.1方式1)  import 'package: scheme';
      //2.1方式二)  import '文件系统路径';
    
      //3.如果导入的库标识符冲突,可通过库前缀解决,例如:import 'package:lib1/lib1.dart' as lib1;
    
      //4.导入库的一部分
      //4.1 import 'package:lib1/lib2.dart' show foo;//仅导入foo部分
      //4.2 import 'package:lib1/lib1.dart' hide foo;//导入除foo之外的其他部分
    
      //5.延迟加载库,使用:deferred as
      //例如:import 'lib1/lib1.dart' deferred as foo;
      //当要使用foo类时,需要调用loadLibrary(),可多次调用,但只会加载一次
      //例如:foo.loadLibrary();
    
      /**
        使用延迟加载库时的注意点
        Keep in mind the following when you use deferred loading:
        1.A deferred library’s constants aren’t constants in the importing file. Remember, these constants don’t exist until the deferred library is loaded.
        2.You can’t use types from a deferred library in the importing file. Instead, consider moving interface types to a library imported by both the deferred library and the importing file.
        3.Dart implicitly inserts loadLibrary() into the namespace that you define using deferred as namespace. The loadLibrary() function returns a Future.
       */
    }
    
    
    • 异步请求
    void main() {
      //异步支持
      //和OC和Swift很不一样,dart语言的库中,几乎所有的函数返回值都是Future或Stream对象。这些函数都是异步的,使用关键词
      //async和await来支持异步编程。
    
      //1.使用await关键词的代码,必须在被标记为async的函数中,例如:
      // Future<void> checkVersion() async {
      //   var version = await lookUpVersion();
      // }
    
      //2.一个async函数中,可以使用多个await。(这种感觉比OC就爽太多了)
      // Future someAsyncFunction() async {
      //   var entryPoint = await findEntryPoint();
      //   var exitCode = await runExecutable(entryPoint, args);
      //   await flushThenExit(exitCode);
      // }
    
      //3.在await表达式中,表达式的值通常是Future类型,如果不是那么这些值就是自动包装在Future中。
    
      //4.声明异步函数(异步函数如果不需要返回值,则返回类型填写Future<void>)
      Future<String> lookUpVersion() async => '1.0.0';
    
      //5.异步请求流处理(用到再看)
    }
    
    • 生成器
    void main() {
      //生成器:当你需要懒加载产生一系列的值时,考虑使用一个生成器函数。
      //关键词:sync*, async*, yield, yield*
      //yield:产出、提供
      //Dart内置支持两种生成器功能:
      //1.同步生成器: 返回 Iterable 对象.例如:自然数生成
      Iterable<int> naturalsTo(int n) sync* {
        int k = 0;
        //简写
        while (k < n) yield k++;
    
        //标准写法
        // while (k < n) {
        //   yield k++;
        // }
      }
    
      var naturals = naturalsTo(10);
      print(naturals.toString()); //打印 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    
      //2.异步生成器: 返回 Stream 对象.
      Stream<int> asyncNaturalsTo(int n) async* {
        int k = 0;
        //简写
        while (k < n) yield k++;
      }
    
      var asyncNaturals = asyncNaturalsTo(5);
      print(asyncNaturals.toString()); //打印  Instance of '_ControllerStream<int>'
    
      //3.递归同步生成器
      Iterable<int> recursiveNaturalsTo(int n) sync* {
        if (n > 0) {
          yield n;
          yield* recursiveNaturalsTo(n - 1);
        }
      }
    
      var recursiveNaturals = recursiveNaturalsTo(8);
      print(recursiveNaturals.toString());//打印  (8, 7, 6, 5, 4, 3, 2, 1)
    }
    
    • 可调用类
    void main() {
      //Callable classes——可以调用的类,让dart类像函数一样被调用。需要实现call()方法。
      var wf = WannabeFunction();
      print(wf('Hi', 'there,', 'gang')); //打印  Hi there, gang!
    }
    
    class WannabeFunction {
      String call(String a, String b, String c) => '$a $b $c!';
    }
    
    • 隔离(Isolates)——用到了再学习
      是一种解决多线程访问同一块内存导致错误的解决方案,详情请查看下面链接:

    相关文章

      网友评论

          本文标题:Dart常用功能语法——只记录和OC、Swift不同的地方

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