Dart学习基础笔记

Dart语言详解


变量-变量的声明

区别于java,新增 var dynamic Object

var:如果没有初始值,可以变成任何类型

dynamic:动态任意类型,编译阶段不检查类型

Object:动态任意类型,编译阶段检查检查类型

区别:

唯一区别 var 如果有初始值,类型被锁定,没有初始化的变量自动获取一个默认值为null,一切皆对象(此对象 非彼对象),对象的默认值为null

变量-final和const

共同点:

1.声明的类型可省略

2.初始化后不能再赋值

3.不能和var同时使用

区别:

1.类级别常量,使用static const

2.const可使用其他const 常量的值来初始化其值

3.使用const赋值声明,const可省略

4.可以更改非final、非const变量的值,即使曾经具有const值

5.const导致的不可变性是可传递的

6.相同的const常量不会在内存中重复创建

7.const需要是编译时常量

内置类型

Numbers 数值、Strings 字符串、Booleans 布尔值、Lists 列表(数组)、Sets 集合、Maps 集合、Runes 符号字符、Symbols 标识符、int : 整数值、double : 64-bit双精度浮点数、int和double是num的子类。

特殊讲解String:

Dart 字符串是 UTF-16 编码的字符序列,可以使用单引号或者双引号来创建字符串,可以使用三个单引号或者双引号创建多行字符串对象,可以使用 r 前缀创建”原始raw”字符串,可以在字符串中使用表达式: ${expression},如果表达式是一个标识符,可以省略 {},如果表达式的结果为一个对象,则 Dart 会调用对象的 toString() 函数来获取一个字符串

内置类型-List:

Dart中可以直接打印list包括list的元素,List也是对象。java中直接打印list结果是地址值

Dart中List的下标索引和java一样从0开始和java一样支持泛型。

有增删改查,支持倒序,自带排序、洗牌,可使用+将两个List合并

内置类型-Set:

set1.difference(set2):返回set1集合里有但set2里没有的元素集合

set1.intersection(set2):返回set1和set2的交集

set1.union(set2):返回set1和set2的并集

set1.retainAll():set1只保留某些元素(要保留的元素要在原set中存在)

内置类型-Runes:

Main(){

  Runes runes = new Runes('\u{1f605} \u6211‘);

  var str1 = String.fromCharCodes(runes); 

  print(str1);

}

Runes用于在字符串中表示Unicode字符。

使用String.fromCharCodes显示字符图形。

如果非4个数值,需要把编码值放到大括号中

函数


函数定义

1.可在函数内定义

2.定义函数时可省略类型

3.支持缩写语法 =>

Dart中函数是Function类型的对象。

所有的函数都返回一个值。如果没有指定返回值,则 默认把语句 return null; 作为函数的最后一个语句执行。

定义函数时可省略类型(不建议)。

对于只有一个表达式的方法,你可以选择 使用缩写语法=>表达式来定义。(Kotlin是用=来实现)

可在函数内部定义函数,支持嵌套。

函数-可选参数:

1.可选命名参数

2.可选位置参数

3.默认参数值

可选命名参数:使用 {param1, param2, …} 的形式来指定命名参数。

可选位置参数:把可选参数放到 [] 中,必填参数要放在可选参数前面。

可选命名参数默认值(默认值必须是编译时常量),可以使用等号‘=’或冒号’:‘。

Dart SDK 1.21 之前只能用冒号,冒号的支持以后会移除,所以建议使用等号。

可选位置参数默认值(默认值必须是编译时常量),只能使用等号'='。

可使用list或map作为默认值,但必须是const。

函数-匿名函数

1.可赋值给变量,通过变量调用

2.可在其他函数中直接调用或传递给其他函数

可以通过()调用,不推荐。

常用的List.forEach()就用的匿名函数。

test((){

print("匿名函数");

});

函数-闭包

Function makeAddFunc(int x) {

  x++;

  return (int y) => x + y;

}

main() {

  var addFunc2 = makeAddFunc(2);

  var addFunc4 = makeAddFunc(4);

  print(addFunc2(3));

  print(addFunc4(3));

}

注:方法体只包含一个语句,可以使用”=>”缩写。

函数-函数别名

typedef Fun1(int a, int b);

typedef Fun2<T, K>(T a, K b);

int add(int a, int b) {

  print('a + b');

  return a + b;

}

定义函数模版示列:typedef fun = int add(int a, int b);

test(fun param){

fun(a,b);

}

class Demo1 {

  Demo1(int f(int a, int b), int x, int y) {

    var sum = f(x, y);

    print("sum1 = $sum");

  }

}

class Demo2 {

  Demo2(Fun1 f, int x, int y) {

    var sum = f(x, y);

    print("sum2 = $sum");

  }

}

class Demo3 {

  Demo3(Fun2<int, int> f, int x, int y) {

    var sum = f(x, y);

    print("sum3 = $sum");

  }

}

注:typedef给函数起一个别名,使用比较方便。例如定义一个方法的回调,直接使用别名定义。

没返回值,则只要参数匹配就行了,如果定义了返回值,则返回值不一样会报错。

操作符:

“?.”,条件成员访问 和 . 类似,但是左边的操作对象不能为 null,例如 foo?.bar 如果 foo 为 null 则返回 null,否则返回 bar 成员。

“~/”,除后取整。

“as”,类型转换。

“is”,如果对象是指定类型返回true。

“is!”,如果对象是指定类型返回false。

“??”,双问号左边为true返回左边结果,否则返回右边结果。

“..”,级联语法。严格来说, 两个点的级联语法不是一个操作符。 只是一个 Dart 特殊语法。

“??:”,如果左边是 null,则右边赋值给左边;如果不是 null,则左边的值保持不变

流程控制语句

if else

for, forEach, for-in

while , do-while

switch case

break , continue

Dart中控制流程语句和Java类似。

List和Set等实现了Iterable接口的类支持for-in遍历元素。


Dart 提供了 Exception 和 Error 类型, 以及一些子类型。还可以定义自己的异常类型。但是,Dart 代码可以抛出任何非 null 对象为异常,不仅仅是实现了 Exception 或者 Error 的对象。

/ 抛出Exception 对象

// throw new FormatException(‘格式异常');

// 抛出Error 对象

// throw new OutOfMemoryError();

// 抛出任意非null对象

// throw '这是一个异常';

所有的 Dart 异常是非检查异常。 方法不一定声明了他们所抛出的异常, 并且你不要求捕获任何异常。

Dart 代码可以抛出任何非 null 对象为异常,不仅仅是实现了 Exception 或者 Error 的对象。

异常-捕获

try {

  throw new OutOfMemoryError();

} on OutOfMemoryError {

  print('没有内存了');

} on Error catch(e) {

  print('Unknown error: $e');

} catch (e, s) {

  print('Exception details: $e');

  print('Stack Trace: $s');

} finally {

  print('end');

}

所有的 Dart 异常是非检查异常。 方法不一定声明了他们所抛出的异常, 并且你不要求捕获任何异常。

Dart 代码可以抛出任何非 null 对象为异常,不仅仅是实现了 Exception 或者 Error 的对象。

可以使用on 或者 catch 来声明捕获语句,也可以 同时使用。使用 on 来指定异常类型,使用 catch 来 捕获异常对象。

catch() 可以带有一个或者两个参数, 第一个参数为抛出的异常对象, 第二个为堆栈信息 (一个 StackTrace 对象)。

可以使用rethrow把捕获的异常重新抛出。


类-构造函数:

//java中写法

class Point {

  double x;

  double y;

  Point(int x, int y) {

    this.x = x;

    this.y = y;

  }

}


//dart建议写法

class Point {

  num x;

  num y;

  Point(this.x, this.y);

}

类-命名构造函数:

class Point {

  num x;

  num y;

  Point(this.x, this.y);

  //命名构造函数

  Point.fromJson(Map json) {

    x = json['x'];

    y = json['y'];

  }

}

使用命名构造函数可以为一个类实现多个构造函数, 或者使用命名构造函数来更清晰的表明你的意图。

类-重定向构造函数:

class Point {

  num x;

  num y;

  Point(this.x, this.y);

  //重定向构造函数,使用冒号调用其他构造函数

  Point.alongXAxis(num x) : this(x, 0);

}

一个重定向构造函数是没有代码的,在构造函数声明后,使用 冒号调用其他构造函数。

类-初始化列表:

import 'dart:math';

class Point {

  //final变量不能被修改,必须被构造函数初始化

  final num x;

  final num y;

  final num distanceFromOrigin;

  //初始化列表

  Point(x, y)

      : x = x,

        y = y,

        distanceFromOrigin = sqrt(x * x + y * y);

}

在构造函数体执行之前可以初始化实例参数。 使用逗号分隔初始化表达式。

初始化列表非常适合用来设置 final 变量的值。

类-调用超类构造函数:

eg:class Parent {

  int x;

  int y;

  //父类命名构造函数不会传递 

  Parent.fromJson(x, y)

      : x = x,

        y = y {

    print('父类命名构造函数');

  }

}

class Child extends Parent {

  int x;

  int y;

  //若超类没有默认构造函数, 需要手动调用超类其他构造函数

  Child(x, y) : super.fromJson(x, y) {

    //调用父类构造函数的参数无法访问 this

    print('子类构造函数');

  }

  //在构造函数的初始化列表中使用super(),需要把它放到最后

  Child.fromJson(x, y)

: x = x,

  y = y,

  super.fromJson(x, y) {

    print('子类命名构造函数');

  }

}

超类命名构造函数不会传递,如果希望使用超类中定义的命名构造函数创建子类,则必须在子类中实现该构造函数。

如果超类没有默认构造函数, 则你需要手动的调用超类的其他构造函数。

调用超类构造函数的参数无法访问 this。

在构造函数的初始化列表中使用 super(),需要把它放到最后。


类-常量构造函数:

class Point2 {

  //定义const构造函数要确保所有实例变量都是final

  final num x;

  final num y;

  static final Point2 origin = const Point2(0, 0);

  //const关键字放在构造函数名称之前,且不能有函数体

  const Point2(this.x, this.y);

}

定义const构造函数要确保所有实例变量都是final。

const关键字放在构造函数名称之前。

类-工厂构造函数:

class Singleton {

  String name;

  //工厂构造函数无法访问this,所以这里要用static

  static Singleton _cache;

  //工厂方法构造函数,关键字factory

  factory Singleton([String name = 'singleton']) =>

      Singleton._cache ??= Singleton._newObject(name);

  //定义一个命名构造函数用来生产实例

  Singleton._newObject(this.name);

}

注:工厂构造函数是一种构造函数,与普通构造函数不同,工厂函数不会自动生成实例,而是通过代码来决定返回的实例对象。

如果一个构造函数并不总是返回一个新的对象,则使用 factory 来定义这个构造函数。

工厂构造函数无法访问this。

类-Setter和Getter:

class Rectangle {

  num left;

  num top;

  num width;

  num height;

  Rectangle(this.left, this.top, this.width, this.height);

  num get right => left + width;

  set right(num value) => left = value - width;

  num get bottom => top + height;

  set bottom(num value) => top = value - height;

}

每个实例变量都隐含的具有一个 getter, 如果变量不是 final 的则还有一个 setter。

可以通过实行 getter 和 setter 来创建新的属性, 使用 get 和 set 关键字定义 getter 和 setter。

getter 和 setter 的好处是,你可以开始使用实例变量,后来 你可以把实例变量用函数包裹起来,而调用你代码的地方不需要修改。

类-抽象类:

1.abstract关键字修饰class

2,.继承的方式使用

3.接口的方式使用

不能被实例化,除非定义一个工厂构造函数。

抽象类通常用来定义接口, 以及部分实现。

抽象类通常具有抽象方法,抽象方法不需要关键字,以分号结束即可。

接口方式使用时,需要重写抽象类的成员变量和方法,包括私有的。

一个类可以implement一个普通类。Dart任何一个类都是接口。

一个类可以implement多个接口。

类-可调用类:

class ClassFunction {

  call(String a, String b, String c) => '$a $b $c!';

}

main() {

  var cf = new ClassFunction();

  var out = cf("dongnao","flutter","damon");

  print('$out');

  print(cf.runtimeType);

  print(out.runtimeType);

  print(cf is Function);

}

实现call()方法可以让类像函数一样能够被调用。

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

推荐阅读更多精彩内容