作者:opLW
目的:在阅读Dart概览后进行的总结,主要记录Dart相比Java的新特性,包括许多亲自实验后的总结。如有错误还望指正😄
其他文章:
Dart – 较Java新特性(一)
Dart – 较Java新特性(三)
目录
6.控制流程语句
- 6.1 if else 和Java相同
- 6.2 for循环,forEach 和Java相同
- 6.3 while 和 do-while 和Java相同
- 6.4 break 和 continue 和Java相同
- 6.5 switch switch语句使用"==“比较整数、字符串、编译时常量、枚举类型。比较双方必须是同类的实例并且不能是子父类关系。被比较的类不能重写”=="符号,也就是限定了switch只能用于比较前面提到的系统自带的类。
- Dart中有代码的case不能缺少break
// Java中允许一个有代码的case没有break语句。 // 如下代码在匹配“A”后不会跳出而是接着执行case“B”的语句,所以打印及结果为 "AB" String code = "A"; switch (code) { case "A": System.out.print("A"); case "B": System.out.print("B"); break; default: System.out.print("null"); } // Dart中,如果有代码的case缺少break语句会引发编译时错误 var command = 'A'; switch (command) { case 'A': print("A"); // ERROR: 丢失 break case 'B': print("B"); break; }
- Dart和Java一样支持空的case 此时会遵循
fall through
原则。// 此时只要command的值匹配到“A”或“B”就会调用print("B") var command = 'A'; switch (command) { case 'A': case 'B': print("B"); break; }
- Dart的switch支持跳转语句 需配合
continue
和标签,continue
语句之后不能有任何语句,相应的此时允许该case没有break语句。var command = 'A'; switch (command) { case 'A': print("A"); continue CaseB; CaseB: case 'B': print("B"); break; }
- Dart中有代码的case不能缺少break
7.函数
-
7.1 简洁返回语句
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;
当函数体除了返回语句外没有别的语句时,可以省略中括号和
return
,转而使用=>
替代,这也称为“箭头语法” -
7.2 隐式返回值 除特别声明返回值外,所有函数都有一个默认的返回值
null
,系统会为没有明确声明返回值的函数默认添加return null
语句。 -
7.3 可选参数 分为命名可选参数和位置可选参数两种
- 命名参数 使用
{param1, param2, …}
来指定命名参数// 定义命名参数 void enableFlags({bool bold, bool hidden}) {...} // 使用命名参数 enableFlags(bold: true, hidden: false);
- 位置参数 将参数放到
[]
中来标记参数是可选的// 定义位置参数 void enableFlags([bool bold, bool hidden]) {...} // 使用位置参数 enableFlags(bold: true, hidden: false);
- 参数默认值 在定义方法的时候,可以使用
=
来定义可选参数的默认值。 默认值只能是编译时常量。 如果没有提供默认值,则默认值为null
。// 为参数添加默认值 void enableFlags({bool bold = false, bool hidden = false}) {...}
- 总结与注意点
- 在一个函数中只允许同时存在命名参数或位置参数,并且命名参数或位置参数必须在参数列表末尾,下面为错误示范:
void fun1(String str1, {String str2 = "A"},[String str3 = "A"]) { //...... } void fun2(String str1, [String str2 = "A"], String str3) { //...... }
- 只有命名参数或位置参数才能设置默认值,下面为错误示范:
void fun1(String str1 = "A", {String str2 = "A"}) { //...... }
- 为参数添加默认值时使用
=
,而使用命名参数时用:
- 命名参数和位置参数的区别
void main() { // 调用有命名参数的函数时,因为可以使用”参数名:“,所以 // 命名参数的顺序可以颠倒 fun1("A", str3: "B", str2: "C"); // 命名参数可以省略 fun1("A", str3: "B"); // 调用有位置参数的函数时,强调的是位置,所以 // 不能使用”参数名:“的形式调用,因此不能颠倒顺序 fun2("A", "B", "C"); // 可以省略,实参会按顺序优先代入位置第一个参数即str2 fun2("A", "B"); } void fun1(String str1, {String str2 = "B", String str3 = "C"}) { //...... } void fun2(String str1, [String str2 = "B", String str3 = "C"]) { //...... }
- 命名参数 使用
-
7.4 main函数 任何应用都必须有一个顶级
main()
函数,作为应用服务的入口。main()
函数返回值为空,参数为一个可选的List<String>
。// 如果程序的main函数有参列表,那么需要这样运行程序 // dart 文件 参数列表 // dart args.dart 1 test void main(List<String> arguments) { print(arguments); }
-
7.5 函数是一等公民 Dart 是一门真正面向对象的语言, 甚至其中的函数也是对象,并且有它的类型
Function
。 这也意味着函数可以被赋值给变量或者作为参数传递给其他函数。 也可以把 Dart 类的实例当做方法来调用。void main() { // 赋值给变量 var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!'; var list = [1, 2, 3]; // 将 printElement 函数作为参数传递。 list.forEach(printElement); } void printElement(int element) { print(element);
-
7.6 匿名函数 匿名函数是没有名字的函数,也可称为lambda或clouse,格式如
(参数列表){函数体}
。同样的参数列表可以有可选参数;函数体除了return
语句外没有其他语句时可以省略为=>
。 -
7.7 局部函数及其变量作用域
bool topLevel = true; void main() { var insideMain = true; void myFunction() { var insideFunction = true; assert(topLevel); assert(insideMain); assert(insideFunction); } }
局部函数即存在于函数中的函数。此时局部函数可以访问外部函数的变量甚至顶级变量,反过来外部函数不能访问局部函数的变量。
-
7.8 词法闭包
- Dart 闭包即一个函数对象,函数可以封闭定义到它作用域内的变量。这样即使函数对象的调用在它原始作用域之外, 依然能够访问在它词法作用域内的变量。
如上代码,最终的输出为void main() { var i = 1; var add1 = makeAdder1(i); print("${add1(1)}"); i = 2; // 修改i的值 print("${add1(1)}"); final a = A(); var add2 = makeAdder2(a); print("${add2(1)}"); a.i = 2; // 修改对象a的属性i print("${add2(1)}"); } /// 返回一个函数,返回的函数参数与 [addBy] 相加。 Function makeAdder1(num addBy) { return (num i) => addBy + i; } // 返回一个函数,返回的函数参数与A的对象的属性i相加。 Function makeAdder2(A a) { return (num i) => a.i + 1; } class A { var i = 1; }
2,2,2,3
。可见,虽然Dart中没有基本类型,都是类。但是闭包在使用外部变量时,对于int
、double
等是直接复制一份的,对于其他类则是传递引用。
- Dart 闭包即一个函数对象,函数可以封闭定义到它作用域内的变量。这样即使函数对象的调用在它原始作用域之外, 依然能够访问在它词法作用域内的变量。
-
7.9 函数相等性比较
- 比较方式 使用“==”符号进行比较
- 比较函数的类型及相应规则 不同类型的函数不相等,下面是相同类型函数的比较:
- 顶级函数 函数签名相同即相等
- 类的静态函数 所属类相同,函数签名相同即相等
- 类的实例函数 所属实例对象相同,函数签名相同即相等
万水千山总是情,麻烦手下别留情。
如若讲得有不妥,文末留言告知我,
如若觉得还可以,收藏点赞要一起。