dart语言笔记

2,311 阅读5分钟

常规的操作语法都一致,记录些差异点

基本类型

var    
number 类型分为int和double

变量不用给设置setter和getter方法,自带。


final 和const区别

const在编译时确定,final在运行时确定。

final f = DateTime.now(); //OK
const c = DateTime.now(); //ERROR Const variables must be initialized with a constant value


数组、列表

数组 可以看成跟 列表 一样。
var list=[] 和 List list = List();


List.isEmpty属性如果集合没有元素,则返回true


tip

      dart的这种线程模型,既解决了Android/iOS这种多线程机制,因为线程抢占等原因,导致IO密集型计算不给力,也解决了js这种纯单线程模型,导致的CPU密集型计算不给力的问题



._internal()  调用构造函数, 可加参数或为空。._internal(param1,param2)


external    具体方法,在其他地方实现。


factory     factory 关键字的功能,当实现构造函数但是不想每次都创建该类的一个实例的时候使用。


?. firtst            获取列表里面第一个


函数

dart中,所有类型都是对象,函数的对象类型是:Function。  可作为参数传递。


函数中的参数

dart中不支持如java、C++类似的重载,而是提供了 可选命名参数 和 可选参数

给参数加{},以paramName:value方式的调用, 可选命名参数。

void funcTest({bool isVisible}){...}

给参数增加 [],则意味着这些参数可以忽略,也就是 可选参数。

void funcTest(bool isExist,[bool isVisible]){...}

备注:flutter库里面有大量的 可选命名参数。


函数本身,也可以作为一个参数传入。



类的定义及初始化

dart中并没有public、protected、private等关键字,声明变量与方法时,前面加上 "_" 即可作为private方法使用。不加,默认为public。 

注意: “_” 的限制范围并不是类级别,而是库访问级别。


静态方法,同其他语言一致


初始化构造函数

class Point{
    num x,y,z;
    Point(this.x,this.y) : z= 0        //初始化常量z
    Point.bottom(num x):this(x,y);  //充定向构造函数
}


代码复用

OOP语言,一般通过继承父类和接口实现,来实现继承。

dart类似,区别点说明:

  1. 继承父类:子类由父类派生,会自动获取父类的成员变量和方法实现,子类可以根据需要复写父类的构造函数及父类方法。   
  2. 接口实现:子类获取到的,只是接口的成员变量符号和方法符号,需要重新实现成员变量,以及方法的生命和初始化,否则,编译期报错。 


dart里面还可以通过混入mixin,来实现类的复用。

class DemoCls with DemoFatherCls{
}

var demoCls = DemoCls();
print(demoCls is DemoFatherCls);// true
print(demoCls is DemoCls);//true

通过混入,一个类可以以非继承的方式,使用其他类中的变量和方法。

ps:mixin 在flutter源码中使用较多。juejin.cn/post/684490…


实操用法:

一般是 单继承、多实现,混入是多继承

  • A、继承是子类需要复用 父类的方法实现。
  • B、实现接口是复用接口的参数、返回值和方法名,但不复用方法的实现。    类比在java中实现一个interface。
  • C、混入是多继承,当被混入的类有多个同名方法时,调用子类的该方法时,会调用with声明的最后一个拥有该方法类中的该方法,同时,混入中的父类不能继承。

dart中的mixins通过创建一个新类来实现,该类会是个覆盖在超类之上的新类。

标记:mixins的顺序代表了从最低级到最高级的继承链。



菱形继承(继承歧义)--问题

前提:父类A, 有B类和C类,都是继承自A类。  一个类D,同时继承自B类和C类。 

条件:A类中有个方法,D类自己没实现,但在B和C类里面都实现了。

问题:当D类调用这个方法时,没法确认是调的是在B类里的实现,还是在C类的实现。



String  byte[]之类的格式装换

import 'dart:typed_data';
String s = new String.fromCharCodes(inputAsUint8List);
var outputAsUint8List = new Uint8List.fromList(s.codeUnits);


引入Dart的标准库

import 'dart:xxx';

引入绝对路径的dart文件

import 'xxx/xxx.dart';

引入Pub包管理仓库https://pub.flutter-io.cn/中的库

import 'package:xxx/xxx.dart';


除法与整除

/       除号
~/      除号,但返回值是整数

相等

操作符是 ==            // 其中两个对象代表 同样内容 的时候返回true。
如果要判两对象是否为 同一个对象,用identical()方法。


类型判定操作符

as     类型转换                            eg:num x=666; x as int;
is     是指定类型,true
is!    不是指定类型,true
var who ="what";
print(who is String);  //true
who=6;   //报错。      用var声明的同时赋值后,值不可再更改。


赋值操作符

= 是最基本的赋值操作符,

??= 
a??=value, 如果a为null,则赋值value给a;如果不为null,则a不变


条件表达式

常见表达式 term ? expr1 : expr2 
另一种     expr1 ?? expr2     (如果expr1是non-null,返回其值;否则执行expr2并返回其接口)。


位运算符

右移 1705 << 4     =   1705 / ( 2^4)  = 106

左移 1705 >> 4     =   1705 *(2^4) 

位运算符也没什么差别,不记录了。


级联操作符

..  一个对象上,多次调用该对象的多个方法或成员。

new Person()
    ..name = "not6"
    ..age = "110"
    ..saySomething();


条件成员访问操作符

需要区分操作符  ?.   和  操作符.  之间的区别

?.  和常规的成员访问操作符 . 相似, 但左边对象不能为null。
如果左边操作对象为null,则返回 null,否则,返回右边的成员。


流程控制

assert断言      ,只会在debug模式下生效。

assert(x < 10);
不符合条件,会抛出一个异常AssertionError。 程序中断





异常

dart的异常有Exception和Error类型,和一些基于这两个类型的子类。但是,同时你可以抛出任何非null的对象作为异常。

eg:
throw 'xyz should be more than 60';      //字串也可以
throw new FormatException('Some Format is wrong');

catch的写法差异

try {  
    //......
} on OutOfLlamasException {
    //doSomething();
}

所有Exception的异常

try { 
    //...
} on Exception catch (e) {  
    print('Unknown exception: $e');
}

所有异常

try { 
    //...
} catch (e,s) {  //catch可以带有一个或两个参数,第二个为堆栈信息
    print('Unknown exception: $e');
}

finally同java


枚举

每个都有index,默认从0开始,没法手动改。

enum Animal {    
    cat,   
    dog,
    bird
}