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<T> = int Function(T a, T b);

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

void main() {
  assert(sort is Compare<int>); // 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);

未完待续~~~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容