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()就用的匿名函数。

函数-闭包

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 a, K b);

int add(int a, int b) {

  print('a + b');

  return 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 f, int x, int y) {

    var sum = f(x, y);

    print("sum3 = $sum");

  }

}

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

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

操作符:

Dart学习基础笔记_第1张图片


“?.”,条件成员访问 和 . 类似,但是左边的操作对象不能为 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学习基础笔记_第2张图片

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

Dart学习基础笔记_第3张图片

/ 抛出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()方法可以让类像函数一样能够被调用。

你可能感兴趣的:(Dart学习基础笔记)