Dart
Dart概述
绑定环境变量
D:\flutter\bin
Flutter和Dart的相关的执行命令
D:\flutter\bin\cache\dart-sdk\bin
Dart DSK 的相关命令的执行路径
D:\flutter.pub-cache\bin
Pub下载的公共模块的执行路径
变量
变量是一个引用,Dart万物皆对象,变量存储的是对象的引用
变量的默认值是null
Dart变量的值不会进行隐式转换(null不会自动转换成false)
const和fianl的区别:const是用来声明编译时能取到的值;final可以用来声明运行时取到的值
const time = DateTime.now();//报错-无法将运行时的值分配给const变量
final time = DateTime.now();//成功-可以将运行时的值分配给final变量
数据类型
Number String Boolean List Set Map 其他
List
通过构造函数声明List和扩展操作符
var l1 = new List.empty(growable:true);//growable 表示是否运行添加元素
l1.add(1);//[1]
var l2 = new List.filled(3,6)//[6,6,6]
//扩展操作符
var l3;
var l4 = [1,...?l3];//问号判断非空
遍历List
- forEach()
遍历列表 - map()
遍历并处理元素,然后生成新的列表 - where()
返回满足条件的数据 - any()
只要有一项满足条件,即返回true - every()
判断是否每一项都满足条件,都满足条件才返回true - 扩展
var pairs = [[1,2],[3,4]]; var flattened = pairs.expand((e)=>e).toList();//[1,2,3,4]
- 折叠
对列表中的每一个元素,做一个累计操作var nums = [1,2,3] int result = nums.fold(2,(p,e) => p * e); //2*(1*2*3)
Set
无序,可以用来去重等;
Map
赋值,如果key不存在,进行赋值,如果key存在,则不赋值
p.putIfAbsent('gender',()=>'男')
根据条件进行删除
p.removeWhere((key,value) => key == 'gender')
其他
- Runes(符文)
Runes对象是一个32位字符对象,可以把文字转换成符号表情或特定的文字
print('\u{1f44d}') => 👍
https://copychar.cc/ - Symbol
在Dart中符号用#开头来表示的标识符 - dynamic
动态数据类型
Dart运算符
- 地板除(~/)
- 类型判断运算符(is | is!)
- 避空运算符(?? | ??=)
- 条件属性访问(?.)
- 级联运算符(…)
myObject.myMethod() //返回myMethod的方法值
myObject…myMethod()//返回myObject对象的引用Set s = new Set(); // s.add(1);s.add(2);s.add(3);s.remove(2); //{1,3} s..add('a') ..add('b') ..add('c') ..remove('b'); //{a,c}
Dart函数
参数
[]可选参数
{}命名参数
闭包
使用时机:既能重用变量,又保护变量不被污染
实现原理:外层函数被调用后,外层函数的作用域对象被内层函数引用着,导致外层函数的作用域对象无法释放,从而形成闭包。可以避免变量污染。
异步函数
Dart中,异步调用通过Future来实现
async函数返回一个Future,await用于等待Future
http.get(url).then((response){});
final response = await http.get(url);
Dart类与对象
构造函数
默认构造函数
与类同名的函数,在实例化时,自动被调用,可以有参数。
命名构造函数
在类中使用命名构造器(类名.函数名)实现多个构造器,可以提供额外的清晰度。
class Point{
num x,y;
//构造函数
Point(x,y){//Point(this.x,this.y)
this.x = x;
this.y = y;
}
//命名构造函数
Point.fromJson({x:0,y:0}){
this.x = x;
this.y = y;
}
}
常量构造函数
如果类生成的对象不会改变,可以通过常量构造函数使这些对象成为编译时常量。
class ImmuteblePoint {
//属性必须通过 final声明
final num x;
final num y;
//常量构造函数,必须通过const声明,且不能有函数体{}
const ImmutablePoint(this.x,this.y)
//通过常量构造函数,把属性变成了常量,所以属性在进行编译之前已经固定,
所以在编译时不再参与计算,提高了不可变对象的编译性能。
}
//常量构造函数,可以当作普通构造函数使用
var p1 = new ImmutablePoint(1,2)
var p2 = new ImmutablePoint(1,2)
print(p1 == p2) //false;与普通构造函数结果相同
//声明不可变对象,必须通过 const 关键字
var p3 = const ImmutablePoint(1,2)
var p4 = const ImmutablePoint(1,2)
print(p3 == p4) //true
工厂构造函数
通过factory声明,工厂函数不会自动生成实例,而是通过代码来决定返回的实例。
需要多次实例化的时候,只需要实例化一次(单例模式)。
class Person {
String name;
static Person instance;
//工厂构造函数
factory Person([String name = '刘备']){
//工厂构造函数中,不能使用this关键字
if(Person.instance == null){
//第一次实例化
Person.instance = new Person.newSelf(name);
}
//非第一次实例化
return Person.instance;
}
Person.newSelf(this.name);
}
访问修饰
Dart类中,默认的访问修饰符是公开的(public)
如果属性或方法以_开头,表示私有的(private),但是如果调用跟声明在同一个作用域,则不起作用。只有把类单独抽离出去,私有属性和方法才起作用
Getter与Setter
Getter(获取器)是通过get关键字修饰的方法
函数没有小括号,访问时也没有小括号(像访问属性一样访问方法)
Setter(修改器)是通过set关键字修饰的方法
访问时,像设置属性一样给函数传参
class Circle {
final double PI = 3.1415;
num r ;
Circle(this.r)
//使用get声明的方法,不能有小括号
num get area {
return this.PI * this.r * this.r;
}
//Setter
set setR(value ){
this.r = value;
}
}
var c = new Circle(10);
print(c.area); //341.15
c.setR = 20;
print(c.area); //1256.6
初始化列表
作用:在构造函数中设置属性的默认值
时机:在构造函数体执行之前执行
语法:使用逗号分隔初始化表达式
场景:常用于设置final常量的值
class Ract {
int height;
int width;
//调用默认构造函数时,给参数赋值,实例化时不需要进行赋值
Ract() : height = 2, width = 10 {
print("${this.height} --- ${this.width}")
}
getArea() {
return this.height * this.width;
}
}
特殊用法
class Point {
double x,y,z;
Point( this.x, this.y, this.z);
//初始化列表的特殊用法——重定向构造函数
Point.twoD(double x, double y) : this(x,y,0)
//定义一个二维的点,定位方法twoD,然后传入给构造函数Point。
}
static
static关键字用来指定静态成员
通过static修饰的属性是静态属性
通过static修饰的方法是静态方法
静态成员可以通过类名称直接访问(不需要实例化)
实例化是比较消耗资源的,声明静态成员,可以提高程序性能
静态方法不能访问非静态成员,非静态方法可以访问静态成员
静态方法中不能使用this关键字
不能使用this关键字,访问静态属性
元数据
元数据以@开头,可以给代码标记一些额外的信息
元数据可以用来库、类、构造器、函数、字段、参数或变量声明的前面
@override 重写
某方法添加该注解后,表示重写了父类中的同名方法
@required 必填
可以通过@required来注解Dart中的命名参数,用来指示它是必填参数
@deprecated 弃用
若某类或某方法加上该注解之后,表示此方法或类不再建议使用
继承
根据类的先后顺序,可以将类分成父类和子类
子类通过extends关键字继承父类
继承后,子类可以使用父类中,可见的内容(属性和方法)
子类中,可以通过@override元数据来标记“覆盖”方法
“覆盖”方法:子类中与父类中同名的方法
子类中,可以通过super关键字来引用父类中,可见的内容
属性
方法(普通构造函数,命名构造函数)
抽象类
抽象类是用abstract关键字修饰的类
抽象类的作用是充当普通类的模板,约定一些必要的属性和方法
抽象方法是指没有方法体的方法
抽象类中一般都有抽象方法,也可以没有抽象方法(抽象方法,只有方法名,没有方法体,直接以;结束)
普通类中,不能有抽象方法
抽象类不能被实例化(不能被new)
抽象类可以被普通类继承(extends)
如果普通类继承抽象类,必须实现抽象类中所有的抽象方法
抽象类还可以充当接口被实现 (implements)
如果把抽象类当做接口实现的话,普通类必须得实现抽象类里面定义的所有属性和方法。
接口
接口在Dart中就是一个类(只是用法不同)
与Java不同,Java中的接口需要用interface关键字声明;Dart中不需要
接口可以是任意类,但一般使用抽象类做接口
一个类可以实现(implements)多个接口,多个接口用逗号分隔
class MyClass implements Interface1,Interface2{…}
接口可以看成一个个小零件。类实现接口就相当于组装零件
普通类实现接口后,必须重写接口中所有的属性和方法
混入 Mixin
混入是一段公共代码。混入有两种声明方式:
将类当作混入 class MixinA{…}
作为Mixin的类只能继承自Object,不能继承其他类
作为Mixin的类不能有构造函数
使用Mixin关键字声明mixin MixinB{…}
混入可以提高代码复用的效率,普通类可以通过with来使用混入
class MyClass with MixinA,MixinB{…}
使用多个混入时,后引入的混入会覆盖之前混入中的重复的内容
MixinA和MixinB中都有hello()方法,MyClass会使用MixinB中的
泛型Generics
泛型是在函数、类、接口中指定宽泛数据类型的语法
- 泛型函数
- 泛型类
- 泛型接口
通常,在尖括号中,使用一个字母来代表类型,例如E、T、S、K和V等。
返回类型 函数名<输入类型>(参数类型 参数){
函数体
}
T getData<T>(T value){
return value;
}
作用:使用泛型可以减少重复的代码
//泛型类
class GenericsClass<T>{
Set s = new Set<T>();
void add(T value){
this.s.add(value);
}
void info(){
print(this.s);
}
}
//实例化泛型类
GenericsClass g = new GenericsClass<int>();
g.add(1)
g.add('2')//报错
//泛型接口
abstract class Cache<T>{
getByKey(String key);
void setByKey(String key, T value);
}
使用泛型限制参数类型
class SomeBaseClass {}
class Foo<T extends SomeBaseClass> {
Sting toString() => "Instance of 'Foo<$T>'";
}
枚举
枚举是数量固定的常量值,通过enum关键字声明
enue Color{red, green, blue}
枚举的values常量,可以获取所有枚举值列表
List<Color> color = Color.values;
可以通过index获取值的索引
assert(Color.green.index) == 1
Dart库与生态
Dart中的库就是具有特定功能的模块
可能包含单个文件,也可能包含多个文件
按照库的作者进行划分,库可以分成三类
自定义库(自己写的)
系统库(Dart中自带的)
第三方库(Dart生态中的)
Dart生态
http://pub.dev/
pub命令(D:\flutter\bin\cache\dart-sdk\bin)
自定义库
通过library声明库
每个Dart文件默认都是一个库,只是没有使用library来显示声明
Dart使用_(下划线)开头的标识符,表示库内访问可见(私有)
library关键字声明的库名称建议使用:小写字母+下划线
通过import来引入库
不同类型的库,引入方式不同
自定义库(import ‘库的位置/库名称.dart’)
系统库(import ‘dart:库名称’)
第三方库
tip:
import 'dart:core'; //core 库会被默认引入
引入部分库(仅引入需要的内容)
包含引入(show)
排除引入(hide)
指定库的前缀
当库名冲突时,可以通过as关键字,给库声明一个前缀
延迟引入(懒加载)
使用deferred as 关键字来标识需要延时加载的库
import 'lib/function.dart' deferred as func;
void main(){
greet();
}
Future greet() async {
await func.loadLibray();//这步表示开始加载,之后可以调用库中的方法
func.hello();
}
通过part与part of来组装库
系统库
系统库(也叫核心库)是Dart提供的常用的内置库
不需要单独下载,就可以直接使用
引入
import ‘dart:库名’;
import ‘dart:core’;//会自动引入(无需手动引入)
系统库列表
https://dart.ac.cn/libraries
第三方库
来源
https://pub.dev
https://pub.flutter-io.cn/packages
https://pub.dartlang.org/flutter
使用
在项目目录下创建pubspec.yaml
在pubspec.yaml中声明第三方库(依赖)
命令行中进入pubspec.yaml所在目录,执行pub get进行安装
项目中引入已安装的第三方库(import ‘package:xxxx/xxxx.dart’)