Dart中文教程_w3cschoolhttps://www.w3cschool.cn/nxvsy/
1. 变量
声明变量
- 使用var来定义变量,变量的类型可以通过变量值推断出来,变量定义后其类型已经确定,不可再将其他类型的值赋给变量。
var name = 'Bob';//String类型
var age= 12; //int类型
name = 3; //此处编译器会报错,name被定义赋值之后已经是一个String类型,不可再赋值int类型值
- 明确指定类型
String name = 'Bob';
-
如果变量不限于单个类型,则可以使用dynamic或Object来定义
dynamic age = 18;
age = "18岁";
Object age = 18;
age = "18岁";
默认值
未初始化的变量默认值是 null。即使变量是数字类型默认值也是 null,因为在 Dart 中一切都是对象,数字类型也不例外。
Final 和 Const
一个final变量只能被设置一次,不能被修改。
const 关键字不仅可以用于声明常量变量。 还可以用来创建常量值,以及声明创建常量值的构造函数。任何变量都可以拥有常量值,定义时必须赋值。
2. 内建类型
Number
int 和 double 都是 num. 的亚类型。
//在 2.1 之前,在 double 上下文中使用 int 字面量是错误的。
double z = 1; // 相当于 double z = 1.0.
字符串与数字转换
// String -> int
var one = int.parse('1');
assert(one == 1);
// String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);
// int -> String
String oneAsString = 1.toString();
assert(oneAsString == '1');
// double -> String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');
String
- 字符串通过单引号或者双引号创建。
- 使用连续三个单引号或者三个双引号实现多行字符串对象的创建
- 字符串可以通过 ${expression} 的方式内嵌表达式。 如果表达式是一个标识符,则 {} 可以省略。
var str = 'string interpolation';
assert('Dart has $str, which is very handy.' ==
'Dart has string interpolation, ' +
'which is very handy.');
assert('That deserves all caps. ' +
'${str.toUpperCase()} is very handy!' ==
'That deserves all caps. ' +
'STRING INTERPOLATION is very handy!');
String str2 = """Hi,Bruce
This is Xiaoming.
""";
print("str2 = $str2");
//输出结果为
str2 = Hi,Bruce
This is Xiaoming.
Boolean
Dart 使用 bool 类型表示布尔值。Dart 只有字面量 true and false 是布尔类型, 这两个对象都是编译时常量。
List(也被称为 Array)
Dart中使用的集合是 array 或有序的对象集合
var list = [1, 2, 3];
//Dart推断list的类型为List<int>。如果尝试将非整数对象添加到此List中,则分析器或运行时会引发错误。
在 List 字面量之前添加 const 关键字,可以定义 List 类型的编译时常量:
var constantList = const [1, 2, 3];
// constantList[1] = 1; // 会引起错误,const不允许修改
Set
在 Dart 中 Set 是一个元素唯一且无序的集合。
var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
//Dart推断halogens类型为 Set<String>。如果尝试为它添加一个错误类型的值,分析器或执行时会抛出错误。
var elements = <String>{};
elements.add('fluorine');
elements.addAll(halogens);
assert(elements.length == 5);
var names = <String>{};
Set<String> names = {}; // 这样也是可以的。
Map
var names = {}; // 这样会创建一个 Map ,而不是 Set 。
// 如果忘记在 {} 上注释类型或赋值到一个未声明类型的变量上,那么Dart会创建一个类型为 Map<dynamic, dynamic> 的对象。
var nobleGases = Map();
nobleGases[2] = 'helium';
//这里为什么只有Map(),而不是使用 new Map()。 因为在Dart 2 中,new 关键字是可选的。
assert(nobleGases['fifth'] == null);
//如果Map中不包含所要查找的key,那么Map返回 null
Rune
Rune用来表示字符串中的 UTF-32 编码字符 Unicode。
- 常用方法是 \uXXXX, 这里 XXXX 是一个4位的16进制数。如小心心(♥)是
\u2665
- 对于特殊的非 4 个数值的情况, 把编码值放到大括号中即可。如笑脸(😆)是
\u{1f600}
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(new String.fromCharCodes(input));
//♥ 😅 😎 👻 🖖 👍
Symbol
一个 Symbol 对象表示 Dart 程序中声明的运算符或者标识符。通过字面量 Symbol ,也就是标识符前面添加一个 # 号,来获取标识符的 Symbol 。
3. 函数
可选参数
可选参数可以是命名参数或者位置参数,但一个参数只能选择其中一种方式修饰。
- 命名参数,定义格式如 {param1, param2, …}
void showInfo({var name, var age}) {
if(name != null) {
print("name = $name");
}
if(age != null) {
print("age = $age");
}
}
// 函数调用
showInfo(name: "Bruce");
//name = Bruce
使用 @required 注释表示参数是 required 性质的命名参数, 该方式可以在任何 Dart 代码中使用(不仅仅是Flutter)。
const Scrollbar({Key key, @required Widget child})
//此时 Scrollbar 是一个构造函数, 当 child 参数缺少时,分析器会提示错误。
- 位置参数,使用 [] 来标记可选参数。
void showInfo(var name, [var age]) {
print("name = $name");
if(age != null) {
print("age = $age");
}
}
// 函数调用
showInfo("Bruce");
//name = Bruce
- 默认值,在定义方法的时候,可以使用 = 来定义可选参数的默认值。 默认值只能是编译时常量。 如果没有提供默认值,则默认值为 null。
void showInfo(var name, [var age = 18]) {
print("name = $name");
if(age != null) {
print("age = $age");
}
}
// 函数调用
showInfo("Bruce");
// name = Bruce
// age = 18
main() 函数
任何应用都必须有一个顶级 main() 函数,作为应用服务的入口。 main() 函数返回值为空,参数为一个可选的 List<String> 。
函数是一等对象
一个函数可以作为另一个函数的参数,可以将一个函数赋值给一个变量。
var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!';
assert(loudify('hello') == '!!! HELLO !!!');
匿名函数
var list = ['apples', 'bananas', 'oranges'];
list.forEach((item) {
print('${list.indexOf(item)}: $item');
});
//如果函数只有一条语句, 可以使用箭头简写。
list.forEach(
(item) => print('${list.indexOf(item)}: $item'));
返回值
所有函数都会返回一个值。 如果没有明确指定返回值, 函数体会被隐式的添加 return null; 语句。
foo() {}
assert(foo() == null);
4. 运算符
算术运算符
+ - -expr * / ~/ % ++var var++ --var var--
assert(5 / 2 == 2.5); // 结果是双浮点型
assert(5 ~/ 2 == 2); // 商,结果是整型
assert(5 % 2 == 1); // 余数
关系运算符
== != > < >= <=
- 如果 x 或 y 可以 null,都为 null 时返回 true ,其中一个为 null 时返回 false。
- 在极少数情况下, 要确定两个对象是否完全相同,需要使用 identical() 函数。
类型判定运算符
as is is!
使用 as 运算符将对象强制转换为特定类型。 通常,可以认为是 is 类型判定后,被判定对象调用函数的一种缩写形式。
if (emp is Person) {
// 判断对象是否为Person类
emp.firstName = 'Bob';
}
// 如果emp为null或者不是Person对象,会抛出异常;如果是Person对象,则为上例的缩写形式
(emp as Person).firstName = 'Bob';
赋值运算符
- 复合赋值运算符(如 += )将算术运算符和赋值运算符组合在了一起。
- 使用 ??= 运算符时,只有当被赋值的变量为 null 时才会赋值给它。
逻辑运算符
!expr || &&
按位和移位运算符
& | ^ ~expr << >>
条件表达式
condition ?expr1 : expr2
如果条件为 true, 执行 expr1 (并返回它的值): 否则, 执行并返回 expr2 的值。
expr1 ?? expr2
如果 expr1 是 non-null, 返回 expr1 的值; 否则, 执行并返回 expr2 的值。
?.
Person p;
var name = p?.name;
// 先判断p是否为null,如果是,则name为null;如果否,则返回p.name值
级联运算符 (..)
级联运算符 (..) 可以实现对同一个对像进行一系列的操作。 除了调用函数, 还可以访问同一对象上的字段属性。
querySelector('#confirm') // 获取对象。
..text = 'Confirm' // 调用成员变量。
..onClick.listen((e) => window.alert('Confirmed!'));
// 等价于
var button = querySelector('#confirm');
button.text = 'Confirm';
button.onClick.listen((e) => window.alert('Confirmed!'));
5. 控制流程语句
if - else
for 循环
while 和 do-while
break 和 continue
switch 和 case
- switch 语句使用 == 比较整数,字符串,或者编译时常量。 比较的对象必须都是同一个类的实例(并且不可以是子类), 类必须没有对 == 重写。 枚举类型 可以用于 switch 语句。
- 在 Dart 中 Switch 语句仅适用于有限的情况下, 例如在 interpreter 或 scanner 中。
- 在 case 语句中,每个非空的 case 语句结尾需要跟一个 break 语句。 除 break 以外,还有可以使用 continue, throw,者 return。
- 当没有 case 语句匹配时,执行 default 代码。
var fruit = 'apple';
switch (fruit) {
case 'banana':
print("this is a banana");
continue anotherFruit;
anotherFruit:
case 'apple':
print("this is an apple");
break;
}
// 输出结果
this is an apple
assert
- assert 语句只在开发环境中有效, 在生产环境是无效的;
- assert 的第一个参数可以是解析为布尔值的任何表达式。 如果表达式结果为 true , 则断言成功,并继续执行。 如果表达式结果为 false , 则断言失败,并抛出异常 (AssertionError) 。
6. 异常
throw
可以抛出任何非 null 对象, 不仅限 Exception 和 Error 对象。
throw 'Out of llamas!';
try - catch
如果仅需要部分处理异常, 那么可以使用关键字 rethrow 将异常重新抛出
try {
breedMoreLlamas();
} on OutOfLlamasException {
// 一个特殊的异常
buyMoreLlamas();
} on Exception catch (e) {
// 其他任何异常
print('Unknown exception: $e');
} catch (e) {
// 没有指定的类型,处理所有异常
print('Something really unknown: $e');
rethrow; // Allow callers to see the exception.
}
finally
不管是否抛出异常, finally 中的代码都会被执行。 如果 catch 没有匹配到异常, 异常会在 finally 执行完成后,再次被抛出。