1 SDK的安装和升级
brew tap dart-lang/dart
brew install dart -devel
验证 :
brew info dart
2 常量和变量
变量
var
未初始化时 ,为null;第一次初始化时,确定类型,一般不可更改类型,(初始化时是Int 可更改为double)
dynamic
常量
final,第一次使用时被初始化<br /> const,编译时常量,隐式的final<br /> 实例变量可以是final,但不能是const;如果是类级别的 可以使用static const ,eg: static const PI = 3.1415
3 内置类型
Number(数值型)
int
double
可以用num,int,double声明
num声明的变量加入的是int型,还可以被改为 double ,但反过来int声明的变量不能再赋值double 型
String
Boolean
List(列表)
Map(键值对)
Runes(符号字符)
Symbols(标识符)
4 数值型操作
运算符:+,-,*,/,~/
常用属性
常用方法
round():四舍五入
floor():返回不大于当前数字的最大整数
ceil():返回不小于该数字的最小整数。
toInt()
toDouble()
abs()
5 字符串
创建
使用单引号,双引号创建字符串
使用三个引号或者双引号创建多行字符串
使用r创建原始字符串
字符串操作
- 运算符: +, *, ==, []
- 插值表达式 : ${expression}
- 常用属性
length
isEmpty
isNotEmpty
- 常用方法
contains()
subString()
startsWith()
endsWith()
indexOf()
lastIndexOf()
toLowerCase()
toUpperCase()
trim():返回没有任何前导和尾随空格的字符串
trimLeft()
trimRight()
split():在指定分隔符的匹配处拆分字符串并返回子字符串列表
replaceAll()
…
6 布尔型
通常用在if条件判断语句里,只有布尔值'true'被视为true
7 null检查
outgoing为null或者outgoing[a]为null或contains(b)的值为null,都会导致表达式为null
8 List(集合)和数组
可以通过[]取出对应下标的元素
常用方法
length()
add()
insert()
remove()
clear()
indexOf()
lastIndexOf()
sort()
sublist()
asMap()
forEach()
shuffle():随机打乱List里的元素的顺序
…
9 Map(键值对):key-value形式存储,键和值都可以是任何类型的对象,每个键只出现一次
直接声明方式创建一个Map
Map game = {"name":"Switch","company":"任天堂"};
创建一个不可变的Map,在Map前面加const
const Map game = const {"name":"Switch","company":"任天堂"};
10 dynamic和Object
Dart里面,一切皆对象,所有对象的父类都是Object
没明确类型时的声明方式
var name1 = 'abc';
Object name2 = 'abc';
dynamic name3 = 'abc';
如果不指定类型,在debug模式下,类型会是动态的,推荐声明时指定类型 String a = ‘abc’;
- dynamic声明时,编译器不做类型检查,如果调用了不存在的方法 ,会执行noSuchMethod(),抛出异常”NoSuchMethodError”
使用as和is进行类型检查
dynamic obj = <String,int>{};
if (obj is Map<String,int>){
obj['age'] = 20;
}
var map = obj as Map<String,int>;
11 异常捕获
抛出异常
throw Exception('name error')
捕获异常
try {
//捕获特定类型的异常
} on OutOfLlamasException catch (e) {
// 捕获特定类型的异常,但不需要这个对象
} on Exception catch (e) {
// 捕获所有Exception异常
print('Unknown exception: $e');
} catch (e) {
// 捕获所有不明类型的异常
print('Something really unknown: $e');
}finally{
//无论是否有异常都会执行
}
12 函数
main()函数
- 可选参数
- 必传参数
- 可选参数
- 默认参数
- 函数作为参数传递
-
13 声明式UI
为了减轻开发人员在各种UI状态之间转换的编程负担,Flutter让开发人员描述当前的UI状态,并且不需要关心它是如何过渡到框架的
14 异步编程
Dart是基于单线程模型的语言,同步代码会阻塞程序
Future对象来执行异步操作
Future是dart:async包中的一个类,是一个自身的的泛型Future
对象,表示一个异步操作产生的T类型的结果,如果结果的值不可用,则为Future Future的常见用法
future.then 获取Future的值与捕获Future的异常
结合async,await
- 使用async将操作放到延迟运算的队列(await)中去,
* async标记的函数,只能由await来调用 ```objectivec String data; setData() async { data = await getData(); //getData()延迟执行后赋值给data }
getData() async { //async关键字声明该函数内部有代码需要延迟执行 return await http.get(Uri.encodeFull(url), headers: {“Accept”: “application/json”}); //await关键字声明运算为延迟执行,然后return运算结果 }
- 使用async将操作放到延迟运算的队列(await)中去,
String data1 = await getData();
* 使用await,必须在有async标记的函数中运行,否则这个await会报错
- future.whenComplete

- future.timeout

<a name="wZTYu"></a>
#### 调用Future函数
- 这个函数加入待完成的队列,并返回一个未完成的Future对象
- 当这个操作结束了,Future对象返回一个值或者错误
<a name="mdtcD"></a>
#### FutureBuilder
构造方法包含三个参数
- future:Future对象表示此构建器当前连接的异步计算;
- initialData:表示一个非空的Future完成前的初始化数据
- builder:AsyncWidgetBuilder类型的回调函数,是一个基于异步交互构建的Widget函数:回调函数接收两个参数,并返回一个Widget
<br />回调函数接收两个参数:<br />BuildContext context<br /> AsyncSnapshot<T> snapshot 包含异步计算的信息<br />1) connectionState异步计算的连接状态:none,waiting,active,done<br />2) data 异步计算接收的最新数据<br />3) error 异步计算接收的最新错误对象<br />4) hasData 检查是否包含非空数据值<br />5) hasError 检查是否包含错误<br />
<a name="C9lrY"></a>
### Dart有自己的进程(或者叫线程)机制,名叫isolate
- APP的启动入口main函数就是一个isolate
- 可以通过引入import 'dart:isolate'创建自己的isolate
- Dart中isolate之间无法直接共享内存,不同的isolate之间只能通过isolate API进行通信
<br />
<a name="XZONX"></a>
### Dart的消息循环机制(event loop) --两个队列
<a name="nhYED"></a>
#### event queue
I/O,mouse events,drawing events,timers,isolate之间的message等。任意isolate中新增的event(I/O,mouse events,drawing events,timers,isolate的message)都会放入event queue中排队等待执行
<a name="qJmMH"></a>
#### microtask queue
只在当前isolate的任务队列中排队,优先级高于event queue
<a name="Vl1iU"></a>
## 15 继承,接口实现和混合
- 继承(extends)
- 接口实现(implements)
- 混合(mixins):在类中混入其他功能
把自己的方法提供给其他类使用,但不需要成为其他类的父类<br /> 要使用mixins,需要用关键字with来复用类中的代码<br /> 优先级(从高到低):本类->mixins->extends->implements
<a name="oO1Xi"></a>
## 16 dart 的构造函数
<br />
<a name="E9tCD"></a>
## 17 泛型
<a name="yO8OM"></a>
### 泛型方法
泛型方法可以约束一个方法使用同类型的参数、返回同类型的值,可以约束里面的变量类型。
```dart
T getData<T> (T val) {
return val;
}
getData<String>('123');
getData<int>(123);
getData<double>(123);
// getData<bool>(123); // Error: The argument type 'int' can't be assigned to the parameter type 'bool'.
泛型类
声明泛型类,比如声明一个 Array 类,实际上就是 List 的别名,而 List 本身也支持泛型的实现
class Array<T> {
List _list = new List<T>();
Array();
void add<T>(T value) {
this._list.add(value);
}
get value{
return this._list;
}
}
使用泛型类
print('----- 泛型类 ------');
List l1 = new List<String>();
// l1.add(12); // type 'int' is not a subtype of type 'String' of 'value'
l1.add('asd');
Array arr = new Array<String>();
arr.add('aa');
arr.add('bb');
// arr.add(123); // type 'int' is not a subtype of type 'String' of 'value'
print(arr.value);
Array arr2 = new Array<int>();
arr2.add(1);
arr2.add(2);
print(arr2.value);
泛型接口
声明了一个 Storage 接口,然后 Cache 实现了接口,能够约束存储的 value 的类型:
abstract class Storage<T>{
Map m = new Map();
void set(String key, T value);
void get(String key);
}
class Cache<T> implements Storage<T> {
@override
Map m = new Map();
@override
void get(String key) {
print(m[key]);
}
@override
void set(String key, T value) {
print('set successed!');
m[key] = value;
}
}
使用泛型接口实现的类:
print('----- 泛型接口 ------');
Cache ch = new Cache<String>();
ch.set('name', '123');
// ch.set('name', 1232); // type 'int' is not a subtype of type 'String' of 'value'
ch.get('name');
Cache ch2 = new Cache<Map>();
// ch2.set('name', '23'); // type 'String' is not a subtype of type 'Map<dynamic, dynamic>' of 'value'
ch2.set('ptbird', {'name': 'pt', 'age': 20});
ch2.get('ptbird');