Dart之旅05:控制流语句

dart常用的控制流语句有以下几个:

  • ifelse
  • for循环
  • whiledo-while循环
  • breakcontinue
  • switchcase
  • assert

你也可以使用try-catchthrow,这个会在异常篇解释。

if和else

dart的if和else和java完全一致,判断式只能使用boolean值,不像php或者js那样可以用0和1之类的判断。

if (isRaining()) {
  you.bringRainCoat();
} else if (isSnowing()) {
  you.wearJacket();
} else {
  car.putTopDown();
}

for循环

for循环和java一样:

var callbacks = [];
for (var i = 0; i < 2; i++) {
  callbacks.add(() => print(i));
}
callbacks.forEach((c) => c());

这避免了js中常见的代码陷阱,这段代码在dart或者像java的语言中输出会是0和1,而在js中输出则是2和2.

dart中的Iterable和java8的Iterable接口一样都含有forEach方法用来提供lambda进行内部循环,简化代码:

candidates.forEach((candidate) => candidate.interview());

Iterable类型例如ListSet同样支持for-in循环:

var collection = [0, 1, 2];
for (var x in collection) {
  print(x); // 0 1 2
}

While和do-while

这个和其他语言相通。

Break和continue

使用break终止循环:

while (true) {
  if (shutDownRequested()) break;
  processIncomingRequests();
}

使用continue来跳过当前循环:

for (int i = 0; i < candidates.length; i++) {
  var candidate = candidates[i];
  if (candidate.yearsExperience < 5) {
    continue;
  }
  candidate.interview();
}

当你使用Iterableforeach方法时你需要使用相应的跳过操作符来跳过循环:

candidates
    .where((c) => c.yearsExperience >= 5)
    .forEach((c) => c.interview());

这里其实就类似RxJava或者RxJs那样了,你也可以理解为Java8的流或者Kotlin的序列。至于这里的执行原理,文档中并未详述。

Switch和case

Switch可以用来比较数字,字符串等编译时常量(也就是可以用const修饰的)。它使用==运算符来比较是否相等。被比较的对象必须是相同类的对象,不能是任何它的子类,并且不能重写==运算符。枚举类型在Switch语句中运行的很优雅。

每个case子句通常被break结束,你也可以使用continue, throw或者return语句。使用default来执行没有case匹配的情况:

var command = 'OPEN';
switch (command) {
  case 'CLOSED':
    executeClosed();
    break;
  case 'PENDING':
    executePending();
    break;
  case 'APPROVED':
    executeApproved();
    break;
  case 'DENIED':
    executeDenied();
    break;
  case 'OPEN':
    executeOpen();
    break;
  default:
    executeUnknown();
}

与java类似,case子句如果不加break则会顺序执行后续case子句。

var command = 'CLOSED';
switch (command) {
  case 'CLOSED': // Empty case falls through.
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}

dart可以为case添加一个标签,让不同的case之间可以通过continue关键字跳转:

var command = 'CLOSED';
switch (command) {
  case 'CLOSED':
    executeClosed();
    continue nowClosed;
  // Continues executing at the nowClosed label.
  case 'OPEN':
    print('OPEN');
    break;
  nowClosed:
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}

这里我开始觉得比较鸡肋,但后来发现这个标签其实是个挺强大的控制方式,他可以实现一个复杂的case流程。读者可以参考Java5之后的枚举状态机模式来推敲这个label的便捷之处,而且其实如果代码比较多的时候整理case子句其实还是挺方便的。

断言Assert

可以使用assert来中断一个出乎意料的执行,这里通常是测试使用,类似Java的单元测试。

// Make sure the variable has a non-null value.
assert(text != null);

// Make sure the value is less than 100.
assert(number < 100);

// Make sure this is an https URL.
assert(urlString.startsWith('https'));

注意:Assert语句在生产环境(就是你打的正式包)中不起作用,它只在开发环境中生效。Flutter在调试模式中开启了断言。

如果想要在断言中添加一句提示信息以供调试可以使用第二个参数:

assert(urlString.startsWith('https'),
    'URL ($urlString) should start with "https".');

断言的第一个参数是bool值,如果是true,则继续运行,如果是false,则抛出异常(AssertionError)。

你可能感兴趣的:(Dart之旅05:控制流语句)