dart基础1

1.尽管dart是强类型语言,但是类型也是可选的。因为dart能够进行类型推断。使用var会自动进行类型推断,如果不想要类型推断的话,那么使用dynamic。

2.dart没有关键字public,protected,private,如果标识符以_开头,则说明它相对于library是私有的。

3.任何和变量进行捆绑的都是对象,无论它是不是基本类型。例如String,Number也是继承自Object类,是祖先类。

4.变量只是存储对象引用,声明定义变量可以有如下方式:

1
2
3
4
5
6
var name = 'bob'; // 会自动进行类型推断为String类型

Object name1 = 'i can change'; // 动态类型,为什么是动态?因为Object是所有对象的祖先类ya
dynamic name2 = 'also change'; // 也是动态类型

String name3 = 'me'; // 显式说明类型

5.在使用过程中不会发生变化的变量可以使用final或者const来声明,final变量的值只能被设置一次;const在编译时则已经固定。如果const变量是类级别的,需要标记为static const。

6.天秀const,像是回到了c指针又像是rust的mut,如下所示:

1
2
3
4
5
const a = 'a';  // 定义一个常量变量a,前面也提到了变量里面存储的是对象引用,所以这个变量a不能再被赋值了,只能指向'a'

var aa = const []; // ???? 秀,这个时候的const是说明右值是不会发生变化的,因此使用aa变量的时候是不能修改到其引用的对象的

aa = 'ok'; // 话还没说完,但是变量aa并不是不可变的,所以变量aa是可以再次赋值,可以更改为指向其它对象的引用

7.String可以通过${expression}的方式内嵌表达式,如果表达式是一个标识符,则{}可以省略。

8.List就相当于js里面的Array,可以看看下面这种使用方法,其知识点正是上面所提到的那个const的地方:

1
2
var arr = const [1,2,3];
// arr[1] = 1; 这种操作是会报错的,因为已经明确声明了变量arr所指向的对象是不可变的

9.Map就像是JavaScript里面的object一样,在一个map对象中一个key只能出现一次,下面介绍一下Map的用法:

1
2
3
4
5
6
7
8
9
10
var gifts = {
'first': '1',
'second': '2'
};
// 使用map字面量来初始化一个对象,会被自动类型推断为Map<String, String>,所以如果有不符合类型推断的key或者value加入进去的话
// 那么将会报错

var m = Map();
m[1] = 'one';
m[2] = 'two';

使用.length方法来获取当前map中的key-value对数量。创建一个Map类型运行时常量:

1
2
3
4
5
final constantMap = const {
2: 'two',
3: 'three',
4: 'four'
};

10.函数:如果函数中只有一句表达式的话,那么可以使用简写语法:

1
bool isNoble(int n) => n !==null;

11.函数的可选参数,函数具有两种参数类型,分别是required类型和optional类型,required类型参数放在参数的最前面,随后optional类型参数。其中可选参数又分为了命名参数和位置参数,一个可选参数只能是其中某一种。

12.命名可选参数,使用这种方式调用函数的时候很奇怪,看着像是js里面的object参数,但是又不是,其实也就是规定了参数的名字,让调用者明白对所传参数的意思更加一目了然?,如下所示:

1
2
void enableFlags({bool bold, bool hidden}) {...} // 这是定义函数时候的模样
enableFlags(bold: true, hidden: false); // 这是调用函数时的模样,很奇怪吧

(注:在flutter中,窗口小部件的构造函数仅使用命名参数),更易于阅读?

使用@required注释表明一个命名参数是必选的,其中@required被定义在package:meta/meta.dart里面,同时其它一些包也将其引入并导出了,比如说package:flutter/material.dart。

1
const fun({String param1, @required bool param2}) {...} // 如果在调用函数的时候没有传params参数的话将会报错

13.位置可选参数,将参数放到[]里面,如下所示:

1
2
3
4
5
6
7
8
9
String say(String from, String msg, [String device]) {
var result = '$from say $msg';
if (device != null) {
result = '$result with $device';
}
return result;
}
say('hai', 'hello');
say('who', 'hello', 'wrchat');

14.默认参数值:可以使用=来定义可选参数的默认值,并且默认值只能是编译时常量,如果没有提供默认值的话,那么默认值为null。

1
2
3
4
5
6
7
8
9
10
void doStuff({
List<int> list = [1,2,3],
Map<String, String> gifts = const {
'first': 'one',
'second': 'two'
}
}) {
print('list: $list');
print('gifts: $gifts');
}

15.main方法,任意一个dart应用都需要main函数,参数为一个可选的List

16.词法闭包

1
2
3
4
5
6
7
8
9
10
11
Function makeFun(num addBy) {
return (num i) => addBy + i;
}

void main() {
var add2 = makeFun(2);
var add4 = makeFun(4);

assert(add2(3) == 5);
assert(add4(3) == 7);
}

17.关于算术操作需要注意的地方:/是返回浮点数;~/返回整数。

18.赋值运算符的花样,dart提供了一个??= 赋值运算符,只有当被赋值变量为null的时候,才会执行赋值操作,如下所示:

1
b ??= value; // 如果b为空的话,将变量赋值给b;否则,b的值保持不变

19.dart给条件表达式所新引入的东西:?? ; 用法如下所示:expr1 ?? expr2,如果expr1是non-null的话,那么返回expr1的值,否则返回expr2的值。

20.级联运算符..,用于支撑起链式调用,但是这里和js里所出现的又有所区别,多加了一个点。

21.流程控制语句:assert,如果assert语句中的布尔条件为false的话,那么正常的程序执行流程会被打断。assert的参数是可以解析成布尔值的任何表达式,如果表达式为true的话,则断言成功,程序继续执行。注,assert语句只在开发环境中有效。

22.对于dart来说,凡是能放到变量里面的都是对象,哪怕是数字,函数,null。每个对象都是某个class的实例,他们共有一个祖先类Object。

23.前面也提到了,只要是能放在变量里面的东西,那么就都是对象。所以对于dart而言,变量里所存储的是数据的引用reference。比如下面这里例子,变量name里面存的是一个reference引用,这个reference指向一个String object,里面的值是bob。

1
var name = "bob";