Dart——初次见面请多指教

Posted by Csming on 2018-05-25

配置环境

Flutter的环境配置在此处不多说明。
笔者在学习Dart时,是在WebStorm上编码的。Dart目前能够使用的IDE是Dart Editor(已被弃用),WebStorm,Atom。我选择了WebStorm。

在WebStorm上配置Dart环境的方法:https://webdev-dartlang-org-dev.firebaseapp.com/guides/get-started

配置完成后就可以创建一个新的控制台项目开始学习了。

Hello World

一个很简单的Hello World。和Java、C++等都一样,Dart从main()函数开始执行。
此处打印了一个hello world。

1
2
3
main(List<String> arguments) {
print('Hello world');
}

Hello World

数据类型

根据万物皆为对象的自然法则,Dart中所有的东西都是对象,都继承于Object,且默认值为null

Dart支持:Numbers、Strings、Booleans、List、Maps这些数据类型。

Strings

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
main(List<String> arguments) {
var str1 = "Hello world";

String str2 = 'Hello world';

var str3 = """hello
world
""";

var str31 = '''hello
world
''';

var str4 = 'hello' 'world';

print("$str4");//5.

print(r"\n");//6.
}

Dart是动态类型语言。
1.可以使用var或者类型来声明变量,而一个变量也可以被指向不同类型的对象。如:str1、str2。
2.对于String类型,其值可用单引号或者双引号。若是使用双引号,则可以内嵌单引号相反亦是。(和js一样)否则需要使用\转移符。
3.可以使用三个单引号或三个双引号包裹多行文字。如:str3、str31。
4.相邻的字符串在编译时或被自动连接。如:str4。
5.如果要连接字符串则可以用相邻连接的方法、Java中的+连接。还可以用模板的方式。如代码中5.所示。利用$或者${}插入。
6.在字符串初始化时,在前面加上字符r可以抵消\的转义作用。如代码中6.所示。

Numbers

num有两个子类型:int和double。分别表示任意长度的证书和双精度浮点数。

const和final

声明变量时,可以使用var还有constfinalconstfinal都为常量。

const:编译时常量,只能用常量初始化
final:可以用变量来初始化

1
2
3
4
5
6
7
const a = 10000;
final b = 100000;
const int c = 1000;
final double d = 1000.1;

var int x = 111;
final int y = x;

函数

函数是一个Function对象。当没有指定的返回值的时候,返回null

函数定义

函数定义的方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
String sayHello(String name) {
print("hello ${name}");
return "hello" + name;
}

sayHello(name) {
print("hello ${name}");
return "hello" + name;
}

sayHello(name) => 'Hello $name';

var sayHello = (name)=>'Hello $name!';

Dart的类型是可选的,所以能够用第二种方式定义。

如果函数知识简单的返回一个表达式的值,则可以用第三种和第四种方式定义方式(匿名函数)。

函数别名

typedef定义函数别名。

1
2
typedef int Add(int a, int b);
int Subtract(int a, int b) => a - b;

函数闭包

(我最讨厌的一个特性,Fuck 闭包)

1
2
3
4
5
6
7
8
9
10
Function makeSubstract(num n)
{
return (num i) => n - i;
}

void main()
{
var x = makeSubstract(5);
print(x(2));
}

对于上述代码,我是这样理解的:
定义的函数makeSubstract返回值为Function类型,其返回一个函数为:

1
(num i) => n - i;

makeSubstract函数中,传入的num n初始化为上述函数的num n值。

然后,在x变量初始化时,获得的就是上述匿名函数所声明的函数。

而最后调用print函数,所传入的2为num i的值。


还有一段代码:

1
2
3
4
5
6
var callbacks = [];
for (var i = 0; i < 3; i++) {
// 在列表 callbacks 中添加一个函数对象,这个函数会记住 for 循环中当前 i 的值。
callbacks.add(() => print('Save $i'));
}
callbacks.forEach((c) => c()); // 分别输出 0 1 2

callbacks被用于存储各个函数对象。而最终依次输出。

可选参数

可选参数分为:命名可选参数和位置可选参数。但二者不共存。

命名可选参数使用{},默认值使用:
位置可选参数使用[],默认值使用=

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FunX(a, {b, c:3, d:4, e})
{
print('$a $b $c $d $e');
}

FunY(a, [b, c=3, d=4, e])
{
print('$a $b $c $d $e');
}

void main()
{
FunX(1, b:3, d:5);
FunY(1, 3, 5);
}

操作符&流程控制语句

1.取整:~/

1
2
3
int a = 3
int b = 2
print(a~/b);//输出1

2.级联:..

对一个单一的对象进行一系列的操作;
类似于Builder模式?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Person {
String name;
String country;
void setCountry(String country){
this.country = country;
}
String toString() => 'Name:$name\nCountry:$country';
}
void main() {
Person p = new Person();
p ..name = 'Wang'
..setCountry('China');
print(p);
}

3.if语句

和其他语言一样。

在checked模式下,会对非bool值的判断语句抛出异常。
而在production模式下,非bool值会被当做false;

4.循环

基本:for循环、whiledo-while
对于迭代对象,可以使用forEach或者for-in。

1
2
3
4
5
6
var collection = [0, 1, 2];

collection.forEach((x) => print(x));//forEach的参数为Function
for(var x in collection) {
print(x);
}

5.switch

switch的参数可以是num、String

6.异常处理

Dart中可以抛出非空对象作为异常:不仅是Exception和Error。

1
2
throw new ExpectException("xxxx");
throw "xxxx";

可以抛出多个类型的Exception,但只能由第一个catch到的分句处理。若catch没有指定类型,则可以处理任何类型的异常。

1
2
3
4
5
6
7
try {
throw 'This a Exception!';
} on Exception catch(e) {
print('Unknown exception: $e');
} catch(e) {
print('Unknown type: $e');
}

结尾可以加上finally语句。