前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >函数、类和运算符:Dart是如何处理信息的?

函数、类和运算符:Dart是如何处理信息的?

作者头像
拉维
发布2019-08-12 15:59:05
9370
发布2019-08-12 15:59:05
举报
文章被收录于专栏:iOS小生活

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

  • 如何表示信息
  • 如何处理信息

之前的文章中,我们已经了解了Dart这门语言的基本语法,也就了解了Dart是如何表示信息的了。今天就来聊聊Dart是如何处理信息的。

作为一门真正面向对象的编程语言,Dart将处理信息的过程抽象成了对象,以结构化的方式将功能分解,而函数、类与运算符就是抽象中最重要的手段。

函数

函数是一段独立完成某功能的代码。在Dart中,所有类型都是对象类型,函数也是对象,它的类型叫做Function。这意味着函数也可以被定义为变量,甚至可以被定义为参数传递给另一个函数

在下面这段代码中,我定义了一个判断整数是否为0 的isZero函数,并把它传递给了printInfo函数,完成格式化打印判断结果的功能:

代码语言:javascript
复制
void main(){
  printInfo(6, isZero);//输出 6 is not Zero
  printInfo(0, isZero);//输出 0 is Zero
}

String isZero (int a){
  return a==0 ? 'is Zero' : 'is not Zero';
}

printInfo(int a, Function check){
  print('$a ${check(a)}');
}

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

C++与Java的做法是,提供函数的重载,即提供同名但是参数不同的函数。但Dart认为重载会导致混乱,因此从设计之初就不支持重载,而是提供了可选参数和可选命名参数

具体方式是,在声明函数时:

  • 给参数增加[],则意味着这些参数是可以忽略的,也就是可选参数;
  • 给参数增加{},以paramName:value的方式调用参数,也就是可选命名参数。

这两者的使用以及区别,我在Dart学习笔记(三)中做了详细说明,这里不赘述。

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

Dart是面向对象的语言,每一个对象都是一个类的实例,都继承自顶层类型Object。

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

接下来看下面一段代码:

代码语言:javascript
复制
void main(){
  var p = Point(66, 88);
  p.printInfo();
  Point.factor = 100;
  Point.printZValue();
}

class Point {
  num x, y;
  static num factor = 0;
  Point(this.x, this.y);
  printInfo() => print('($x, $y)');
  static printZValue() => print(factor);
}

我在Point类中,定义了两个成员变量x和y,通过构造函数进行初始化,成员函数printInfo的作用是打印它们的信息;而类变量factor则在声明时就已经赋好了默认值0,类函数printZValue会打印出它的信息。

有的时候,类的实例化需要根据参数提供多种初始化方式。除了可选命名参数和可选参数之外,Dart还提供了命名构造函数的方式,使得类的实例化过程语义更清晰。

下面再看一段代码:

代码语言:javascript
复制
void main(){
  var p = Point.bottom(66);
  p.printInfo();//输出 (66, 0, 0)
}

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

如代码所示,Point类中有两个构造函数Point与Point.bottom,其中Point.bottom将其成员变量的初始化重定向到了Point中,而Point则在初始化列表中为赋上了默认值0

运算符

在Dart中,一切都是对象,就连运算符也是对象成员函数的一部分

对于系统的运算符,一般情况下只支持基本数据类型和标准库中提供的类型。而对于用户自定义的类,如果想支持基本操作,比如比较大小、相加相减等,则需要用户自己来定义这个运算符的具体实现。

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

接下来我们一起来看一个Vector类中自定义"+"运算符和覆写"=="运算符的例子:

代码语言:javascript
复制
void main(){
  final x = Vector(3, 3);
  final y = Vector(2, 1);
  final z = Vector(1, 2);

  print(z==x+y);//false
  print(x==y+z);//true
}

class Vector {
  num x, y;
  Vector(this.x, this.y);
  //自定义相加运算符,实现向量相加
  Vector operator+ (Vector v) => Vector(x+v.x, y+v.y);
  //覆写相等运算符,判断向量相等
  //需要注意的一点是,这里之所以要用dynamic而不是Vector,是因为operator==继承自Object类,该类的参数声明就是dynamic
  bool operator== (dynamic v) => x == v.x && y == v.y;
}

operator是Dart的关键字,与运算符一起使用,表示一个类成员运算符函数。我们可以这样理解:将operator和运算符作为一个整体,看作是一个成员函数名

总结

函数,类和运算符是Dart处理信息的抽象手段。

函数是对象,可以被定义为变量,或者参数。Dart不支持函数重载,但是提供了可选参数和可选命名参数的方式,从而解决了函数声明时需要传递多个参数的可维护性。

类提供了数据和函数的抽象复用能力,可以通过继承(父类继承extents,接口实现implement)和非继承(Mixin, with)的方式实现复用

以上。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS小生活 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档