作者:opLW
目的:在阅读Dart概览后进行的总结,主要记录Dart相比Java的新特性,包括许多亲自实验后的总结。如有错误还望指正😄
目录
6.控制流程语句
7.函数
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;
}
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
等是直接复制一份的,对于其他类则是传递引用。
- 7.9 函数相等性比较
- 比较方式 使用“==”符号进行比较
- 比较函数的类型及相应规则 不同类型的函数不相等,下面是相同类型函数的比较:
- 顶级函数 函数签名相同即相等
- 类的静态函数 所属类相同,函数签名相同即相等
- 类的实例函数 所属实例对象相同,函数签名相同即相等
万水千山总是情,麻烦手下别留情。
如若讲得有不妥,文末留言告知我,
如若觉得还可以,收藏点赞要一起。