作者: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中没有基本类型,都是类。但是闭包在使用外部变量时,对于intdouble等是直接复制一份的,对于其他类则是传递引用。
  • 7.9 函数相等性比较
  • 比较方式 使用“==”符号进行比较
  • 比较函数的类型及相应规则 不同类型的函数不相等,下面是相同类型函数的比较:
  • 顶级函数 函数签名相同即相等
  • 类的静态函数 所属类相同,函数签名相同即相等
  • 类的实例函数 所属实例对象相同,函数签名相同即相等

万水千山总是情,麻烦手下别留情。
如若讲得有不妥,文末留言告知我,
如若觉得还可以,收藏点赞要一起。