Dart语法快速上手三《Dart2之方法》

这里开始讲Dart语法中最重要的元素之一:方法,Dart里面的方法跟java还是有很大的不同

方法

Dart是一种真正的面向对象语言,因此即使是函数也是对象并且具有类型Function。
这意味着函数可以分配给变量或作为参数传递给其他函数。
您也可以像调用函数一样调用Dart类的实例。

bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

这是一个标准的方法,其中返回类型是可以省略的,Dart会自动推断,而它下面的那个方法则是一个方法的简写版

  • 可选参数和必选参数
    函数可以有两种类型的参数:必需和可选。首先列出所需参数,然后列出任何可选参数。命名的可选参数也可以标记为@required。当我们调用一个方法的时候,我们可以给方法填上一个默认值,例如:
//这是一个可选参数的的方法
  optionalFunction({int a = 1 ,int b =2}){
   return a+b;
 }

//在调用的时候我可以选择传一个参数,也可以选择不传
main(){
optionalFunction(a:4);
optionalFunction(a:4,b:1);
optionalFunction(4,1);//TODO 错误!!!!
optionalFunction();
}

注意,这个方法在调用的时候不能像kotlin一样通过参数的顺序来指定参数,可选参数的方法传参必须在前面加上方法的参数名,来指定参数的值
如果我在可选参数前面加上@Required注解,就表明在这一群可选参数中,这个参数是必传项,不去传递这个参数是非法的

  optionalFunction({int a = 1 ,@required int b }){

   return a+b;

 }
optionalFunction(a:4);  //非法。必须传递b的值

注意:@Required 注解需要导入外部包才能使用
可以直接导入包:meta / meta.dart,也可以导入另一个导出meta的包,例如Flutter的包:flutter / material.dart。

  • 可选位置参数
    可选位置参数的意思就是即使你不传入这个参数,也可以调用这个方法,在上面一个例子中我们发现
  optionalFunction({int a = 1 ,int b =3 }){

   return a+b;

 }

这个方法,如果调用的时候是这样调用的

optionalFunction(4);

这样编译是过不了的,系统不知道你这个4是a还是b
但是可选参数中这样调用是可以的,即使你这个可选参数没有默认值,看代码

String say(String from, String msg, [String device]) {
  var result = '$from says $msg';
  if (device != null) {
    result = '$result with a $device';
  }
  return result;
}

assert(say('Bob', 'Howdy') == 'Bob says Howdy');
assert(say('Bob', 'Howdy', 'smoke signal') ==
    'Bob says Howdy with a smoke signal');

在上面这个示例中,第三个参数device在第一次调用中是没有传递的,但是编译器没有报错,这就是可选位置参数与全部可选参数的区别

级联表示法

级联类似于java里面的build设计模式,可以通过单行一系列的语法操作一个对象

class Grammar2 {
  var x, y, z;
}
var g2 = Grammar2();
    g2 ..x = 1 ..y = 2..z=3;//这样就完成了一系列的赋值
等价于
g2.x = 1; g2.y=2;g2.z=3;


  querySelector('#sample_text_id')
    ..text = 'Click me!'
    ..onClick.listen(reverseText);

Functions as first-class objects(这个感觉翻译成中文怪怪的)

你可以传递一个方法当作一个参数传递给另一个方法

void printElement(int element) {
  print(element);
}

var list = [1, 2, 3];

// Pass printElement as a parameter.
list.forEach(printElement);

上面这是一个简单版本的方法传递,这里延伸一下方法传递的概念Typedefs,java里面是没有方法当作参数的概念的,Dart将这个玩的很6,我们看看Typedefs

Typedefs

在Dart中,函数是对象,就像string和int一样,typedef或为函数类型提供了在声明字段和返回类型时可以使用的名称。当函数类型分配给变量时,typedef会保留类型信息。

class SortedCollection {
  Function compare;

  SortedCollection(int f(Object a, Object b)) {
    compare = f;
  }
}

// Initial, broken implementation.
int sort(Object a, Object b) => 0;

void main() {
  SortedCollection coll = SortedCollection(sort);

  // All we know is that compare is a function,
  // but what type of function?
  assert(coll.compare is Function);
}

上面这种是普通的方法传递的代码,就跟注释上面的疑问一样,都知道这个传递进来的f是一个方法,但是是什么类型的方法呢?
这个时候typedef就派上用场了将f分配给比较时,类型信息会丢失。f的类型是(Object,Object)→int(其中→表示返回),但比较的类型是Function。
如果我们将代码更改为使用显式名称并保留类型信息,则开发人员和工具都可以使用该信息。

typedef Compare = int Function(Object a, Object b); //typedef关键字需要定义在class的外围

class SortedCollection {
  Compare compare;

  SortedCollection(this.compare);
}

// Initial, broken implementation.
int sort(Object a, Object b) => 0;

void main() {
  SortedCollection coll = SortedCollection(sort);
  assert(coll.compare is Function);
  assert(coll.compare is Compare);
}

也可以增加泛型

typedef Compare = int Function(T a, T b);

int sort(int a, int b) => a - b;

void main() {
  assert(sort is Compare); // True!
}

方法的注解

Dart常用的有@override和@deprecated意思跟java一样,这里略过

匿名方法

也称作为无名方法,顾名思义,就是这个方法没有方法名,其他的跟普通方法一样。举个例子:如果我们初始化一个值ax,这个ax的值需要从一个方法的返回值中拿到,在java里面我们这么做

int ax = getAx(9);
int getAx(int a){
  return a *2;
}

Dart中是这样的
var ax = (a) => a2;
是不是简洁了很多?那么无名方法在哪里呢?就是这个(a)=>a
2这个方法除了没有名字,其他跟上面的一样
第二个应用场景就是有些方法需要你传递一个方法进去,第一种办法是上面我们例子说的,定义一个普通方法传递进去

int sort(Object a, Object b) {
......
}
functionPass(sort);  //普通方法

//无名的写法是这样的

void functionPass((Object a, Object b){
.......
})

//更加常用的地方的是
var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
  print('${list.indexOf(item)}: $item');
});

方法的返回值

这里单独提一下方法的返回值,默认情况下dart的方法不写返回值不代表没有返回值,他的返回值是null

foo() {}

assert(foo() == null);

未完待续~~~~~

你可能感兴趣的:(Dart语法快速上手三《Dart2之方法》)