一、Dart基础知识
1、程序入口
每个Dart
程序都需要有一个main()
方法,main()
方法是Dart
程序执行的入口,因此用Dart
写的Hello, world
程序如下:
void main() {
print('Hello, world');
}
2、强制分号
和JavaScript
不同的是,Dart
强制使用分号;
3、自动类型推断
Dart
是强类型语言,但是支持自动推断,所以实例中,可以不写void
4、重要概念
Dart
没有访问控制符
(即public
、protected
、private
),但是如果一个标识符以_
开头,则表示它在 库内 是私有的- 标识符可以以字母或者
_
开头,后面可以跟其他字符或者数字(注意,Dart
不支持$
符,也不支持Unicode作为变量名) Dart
中所有能够使用变量引用的都是对象
,每个对象都是一个类
的实例,数字、方法、null
都是对象,所有对象都继承自Object
类Dart
中函数是可以嵌套声明的
二、Dart变量
1、声明变量
可以使用如下语法[var|<Type>] variableId
声明一个变量
2、默认值
声明变量的时候,可以直接进行赋值操作,所赋予的这个值就是默认值。
注意:如果一个变量没有指定初始值,那么 它的初始值是
null
,int
类型的变量初始值也是null
,这是因为Dart
中数字类型也是对象
3、Final和Const
如果一个变量声明后不打算修改其值,那么可以把这个变量声明为final
或者const
,他们的区别在于:
final
只能在初始化时赋值一次,后续值不可以修改const
同时也是final
,区别在于const
更加严格,它是编译时常量,也就是说如果一个变量声明为了const
,那么应该是在非运行时就能得到这个值,即:
int getNum() {
return 1;
}
void main() {
final a = getNum(); // 没问题
const b = getNum(); // 报错
}
三、内置类型
Dart内置如下的类型:
numbers
strings
booleans
lists
maps
runes
(用于在字符串中表示Unicode字符)symbols
1、Numbers(数值)
Dart支持两种类型的数值:int
和double
,它们都是num
类的实例。num
类型定义了基本的操作符,如+
/-
/*
//
,以及abs()
、ceil()
、floor()
等函数,而int
子类中还定义了位操作符(如>>
)
注意: 对于int类型,溢出的数值(不在-2^53 ~ 2^53范围内的)的表现和
JavaScript
中不一样,Dart
具有任意精度的证书,但是JavaScript
没有
以下是数值类型的一些示例:
int x = 1;
int hex = 0xA;
double y = 1.1;
double z = 1.42e5;
int
类型支持位操作:
assert((3 << 1) == 6);
assert((3 >> 1) == 1);
assert((3 | 4) == 7);
字符串可以和数值互转,如:
// String -> init
var one = int.parse('1');
assert(one == 1);
// String -> double
var oneDotOne = double.parse('1.1');
assert(oneDotOne == 1.1);
// int -> String
String strOne = 1.toString();
assert(strOne == '1');
// double -> String
String strOneDotOne = 1.1.toStringAsFixed(1);
assert(strOneDotOne == '1.1');
注意: 数字字面量为
编译时常量
,只要操作数是常量,那么表达式的结果也是编译时常量
2、Strings(字符串)
Dart字符串是UTF-16编码的字符序列,可以用单引号也可以用双引号:
var s1 = 'single quotes';
var s2 = "double quotes";
Dart同样支持模板字符串,语法为:${expression}
,如果expression
是一个变量,那么可以省略{}
,即为$varibale
。如果表达式的结果是一个对象,那么会调用对象的toString()
方法:
var s = 'World';
print('Hello, $s'); // 输出:Hello, World
var s2 = 100;
print('$s2 * 10 = ${s2 * 10}'); // 输出:100 * 10 = 1000
Dart中连接两个字符串,使用的是+
符号,即为:
var s1 = 'Hello';
var s2 = 'World';
print(s1 + s2); // 输出:'HelloWorld'
如果要创建多行字符串,可以使用'''
或者"""
,如:
var s = '''
This is
a multi-line string
''';
还可以使用r
前缀来创建一个原始(raw)字符串
,如下:
var s = r'This a raw string, even \n is not special';
// 返回:This a raw string, even \n is not special
字符串字面量是编译时常量。如果一个字符串带有插值,那么如果字符串插值内引用的表达式或者变量计算结果也是编译时常量,那么这个字符串就也是编译时常量,如:
const aConstNum = 0;
const aConstBool = true;
const aConstString = 'a constant string';
var aNum = 0;
var aBool = true;
var aString = 'a string';
const aConstList = const [1, 2, 3];
// 以下字符串是合法的,因为它所引用的也都是编译时常量
const validConstString = '$aConstNum $aConstBool $aConstString';
// 但是下面这个就是非法的,因为所引用的不全是编译时常量
const invalidConstString = '$aNum $aBool $aString $aConstList';
3、Booleans(布尔值)
Dart中有名字为bool
的类型,它有两个实例对象:true
和false
,这两个对象都是编译时常量。当Dart需要一个布尔值的时候,只有true
对象才是true
,其他的都是false
(这是和JavaScript
比较不一样的,JavaScript
中truthy
的值都被认为是true):
var name = 'Ruphi';
if (name) {
print('Hello, $name');
}
以上代码在生产模式下什么都不会输出,在检查模式下则会抛出一个异常,表示name
不是一个布尔值,所以需要特别注意和JavaScript
的差异:
if (1) {
print('JS prints this line');
} else {
print('Dart in production prints this line.');
// But in checked mode it throws an exception
}
因此,在Dart中,我们应该 显式地 判断一个变量,确保其计算结果是布尔型的
4、Lists(列表)
Dart中的数组称为List
,其字面量语法示例如下:
var list = [1, 2, 3];
List的下标索引范围为0 ~ list.length - 1
,所以遍历一个list
的方法如下:
int i;
List list = [1, 2, 3, 4, 5];
for (i = 0; i < list.length; ++i) {
print(list[i]);
}
如果在list字面量
前加一个const
关键字,那么可以定义为一个不变的list对象(也就是编译时常量),如:
const constantList = const [1, 2, 3];
constantList[1] = 1; // 报错
5、Maps
Dart中用Map
来表示键值对相关的对象,键和值可以是任何类型的对象,但是 每个键只能出现一次。Dart中使用map
可以通过map字面量
和Map类型
,如:
var fruits = {
'apple': '苹果',
'banana': '香蕉'
};
var numMap = {
1: '壹',
2: '贰'
};
或者也可以使用构造函数实现一样的功能:
var fruits = new Map();
fruits['apple'] = '苹果';
fruits['banana'] = '香蕉';
const numMap = new Map();
numMap[1] = '壹';
numMap[2] = '贰';
创建完后,是可以继续向map中加入键值对的,也可以访问已加入的键值对,都是采用[]
语法:
fruits['pear'] = '梨子';
fruits['apple']; // 返回 '苹果'
可以使用length
来访问map
中键值对的对数,也可以用const
来将map
声明为编译时常量
6、Runes
在Dart中,runes代表字符串的UTF-32 Unicode
,Unicode
为每一个字符、标点符号、表情符号等都定义了一个唯一的数值,但是Dart字符串
是UTF-16
的字符序列,所以如果要表达UTF-32
的字符,那么就需要用Runes
通常而言,表示Unicode字符的语法是:\uXXXX
,XXXX
表示的是4个16进制数,而1个16进制数需要用4位来表示,4个XXXX则是16位,即为UTF-16
,那么对于UTF-32
而言,它需要32位来表示来表示一个Unicode,而对于这些字符,所采用的语法则是:\u{XXXX...}
,如笑脸的emoji是\u{1f600}
而包含UTF-32
字符的字符串,就要采用Runes
了,如下:
main() {
var clapping = '\u{1f44f}';
print(clapping);
print(clapping.codeUnits);
print(clapping.runes.toList());
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}'
);
print(new String.fromCharCodes(input));
}
输出如下图所示: