zoukankan      html  css  js  c++  java
  • Dart函数、类和运算符-处理信息

    编程语言虽然千差万别,但归根结底,它们的设计思想无非就是回答两个问题:

    1、如何表示信息;

    2、如何处理信息;

    函数

    函数是一段用来独立地完成某个功能的代码。函数是对象类型,它的类型叫做Function。这意味着函数也可以被定义为变量,甚至可以被定义为参数传递给另一个函数。
    bool isZero(int number) => number == 0;
    void printInfo(int number, Function check) => print("$number is Zero: ${check(number)}");
    
    如果函数体只有一行表达式,就可以像JavaScript语言那样用箭头函数来简化这个函数

    一个函数中可能需要传递多个参数。如何让这类函数的参数声明变得更加优雅、可维护,同时降低调用者的使用成本?

    C++与Java的做法是,提供函数的重载,即提供同名但参数不同的函数。但Dart认为重载会导致混乱,因此从设计之初就不支持重载,而是提供了可选命名参数和可选参数。
    bool isZero(int number) => number == 0;
    void printInfo(int number, Function check) => print("$number is Zero: ${check(number)}");
    
    // 要达到可选命名参数的用法,那就在定义函数的时候给参数加上{}
    void enableFlagsA({bool bold, bool hidden}) => print("$bold, $hidden");
    
    // 定义可选命名参数时增加默认值
    void enableFlagesB({bool bold = true, bool hidden = false}) => print("$bold, $hidden");
    
    // 可忽略的参数在函数定义时用[]符号指定
    void enableFlagesC(bool bold, [bool hidden]) => print("$bold, $hidden");
    
    // 定义可忽略参数时增加默认值
    void enableFlagesD(bool bold, [bool hidden = false]) => print("$bold, $hidden");
    

    类是特定类型的数据和方法的集合,也是创建对象的模版。

    类的定义及初始化

    Dart是面向对象的语言,每个对象都是一个类的实例,都继承自顶层类型Object。 Dart中并没有public、protected、private这些关键字,只要在声明变量与方法时,在前面加上_即可作为private方法使用,如果不加_,则默认为public。不过_的限制范围并不是类访问级别的,而是库访问级别。

    class Point {
      
      num x, y;
      static num factor = 0;
      // 语法糖,等同于在函数体内:this.x = x; this.y = y;
      Point(this.x, this.y);
      void printInfo() => print('($x,$y)');
      static void printZValue() => print('$factor');
    }
    
    有时候类的实例化需要根据参数提供多种初始化方法。除了可选命名参数和可选参数之外,Dart还提供了命名构造函数的方式,使得类的实例化过程语义更清晰。

    此外,与C++类似,Dart支持初始化列表。在构造函数的函数体真正执行之前,还有机会给实例变量赋值,甚至重定向至另一个构造函数。

    class Point {
      num x, y, z;
      Point(this.x, this.y) : z = 0; // 初始化变量z
      Point.bottom(num x) : this(x, 0); // 重定向构造函数
      void printInfo() => print('($x, $y, $z)');
    }
    
     var p = Point.bottom(100);
     p.printInfo(); // 输出(100,0,0)
     
    

    复用

    在面向对象的编程语言中,将其他类的变量与方法纳入本类中进行复用的方式一般有两种:继承父类和接口实现。

    在Dart中,可以对同一个父类进行继承或接口实现:
    • 继承父类意味着,子类由父类派生,会自动获取父类的成员变量和方法实现,子类可以根据需要覆写构造函数及父类方法;
    • 接口实现则意味着,子类获取到的仅仅是接口的成员变量符号和方法符号,需要重新实现成员变量,以及方法的声明和初始化,否则编译器会报错。
    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,3var yyy = Coordinate();
      yyy
        ..x = 1
        ..y = 2; // 级联运算符,等同于 yyy.x = 1; yyy.y = 2;
      yyy.printInfo(); // 输出 (1,2print(yyy is Point); // true
      print(yyy is Coordinate); // true
    
    除了继承和接口实现之外,Dart还提供了另一种机制来实现类的复用,即“混入"(Mixin),混入鼓励代码重用,可以被视为具有实现方法的接口。不仅可以解决Dart缺少对多重继承的支持问题,还能够避免由于多重继承可能导致的歧义(菱形问题)。

    要使用混入,只需要with关键字即可。

    class Coordinate with Point {
    
    }
    
      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和绝大多数编程语言的运算符一样,除外,Dart多了几个额外的运算符,用于简化处理变量实例缺失(即null)的情况。
    • ?. 运算符:假如Point类有printInfo()方法,p是Point的一个可能为null的实例。那么,p调用成员方法的安全代码,可以简化为p?.printInfo(),表示p为nul的时候跳过,避免抛出异常。
    • ??= 运算符:如果a为null,则给a赋值value,否则跳过。这种用默认值兜底的赋值语句在Dart中我们可以用a ??= value表示。
    • ?? 运算符:如果a不为null,返回a的值,否则返回b。在Java或者C++中,我们需要通过三元表达式(a != null)? a:b 来实现这种情况。而在Dart中,这类代码可以简化为 a ?? b。
    在Dart中,一切都是对象,就连运算符也是对象成员函数的一部分。
    对于系统的运算符,一般情况下只支持基本数据类型和标准库中提供的类型。而对于用户自定义的类。如果想要支持基本操作,比如比较大小、相加相减等,则需要用户自己来定义关于这个运算符的具体实现。

    Dart提供了类似C++的运算符覆写机制,使得我们不仅可以覆写方法,还可以覆写或者自定义运算符。

    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
    
    operator 是 Dart 的关键字,与运算符一起使用,表示一个类成员运算符函数。在理解时,我们应该把 operator 和运算符作为整体,看作是一个成员函数名。
  • 相关阅读:
    每日一篇文献:Robotic pick-and-place of novel objects in clutter with multi-affordance grasping and cross-domain image matching
    每日一篇文献:Intuitive Bare-Hand Teleoperation of a Robotic Manipulator Using Virtual Reality and Leap Motion
    每日一篇文献:Virtual Kinesthetic Teaching for Bimanual Telemanipulation
    HEBI Robotic Arm VR Teleoperation
    「iQuotient Case」AR device teleoperated robotic arm
    VR and Digital Twin Based Teleoperation of Robotic Arm
    HEBI Robotic Arm VR Teleoperation
    Human Robot Interaction
    Immersive Teleoperation Project
    机器人演示学习
  • 原文地址:https://www.cnblogs.com/shsuper/p/11574088.html
Copyright © 2011-2022 走看看