Dart语法超光速入门(3):操作符与控制流

前言

本篇文章参考自Dart官方文档。今天来讲解编程语言中最主要的部分,因为所有的逻辑都要依附于操作符和控制流。

运算操作符

加减乘除取余。
'~/'表示除得的结果为整数。

assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5); // Result is a double
assert(5 ~/ 2 == 2); // Result is an int
assert(5 % 2 == 1); // Remainder

assert('5/2 = ${5 ~/ 2} r ${5 % 2}' == '5/2 = 2 r 1');

++ --和其他语言的都一样了。

var a, b;

a = 0;
b = ++a; // Increment a before b gets its value.
assert(a == b); // 1 == 1

a = 0;
b = a++; // Increment a AFTER b gets its value.
assert(a != b); // 1 != 0

a = 0;
b = --a; // Decrement a before b gets its value.
assert(a == b); // -1 == -1

a = 0;
b = a--; // Decrement a AFTER b gets its value.
assert(a != b); // -1 != 0

相等性判断

assert(2 == 2);
assert(2 != 3);
assert(3 > 2);
assert(2 < 3);
assert(3 >= 3);
assert(2 <= 3);

类型判断

有as,is is!三种。
使用as类似java中类型强转,然后可以调用相应类型的方法。
is用来判断是不是某种类型,而is!则和is相反,判断不是某种类型。

if (emp is Person) {
  // Type check
  emp.firstName = 'Bob';
}
(emp as Person).firstName = 'Bob';

赋值运算符

b??= value表示如果b是null的话则把value赋予b,否则不改变b的值

// Assign value to a
a = value;
// Assign value to b if b is null; otherwise, b stays the same
b ??= value;

逻辑运算符

if (!done && (col == 0 || col == 3)) {
  // ...Do something...
}

位运算

final value = 0x22;
final bitmask = 0x0f;

assert((value & bitmask) == 0x02); // AND
assert((value & ~bitmask) == 0x20); // AND NOT
assert((value | bitmask) == 0x2f); // OR
assert((value ^ bitmask) == 0x2d); // XOR
assert((value << 4) == 0x220); // Shift left
assert((value >> 4) == 0x02); // Shift right

条件表达式

condition ? expr1 : expr2
如果condition为true,返回expr1,否则返回expr2

var visibility = isPublic ? 'public' : 'private';

expr1 ?? expr2
expr1为null的话返回expr2,否则返回expr1自身

String playerName(String name) => name ?? 'Guest';

级联表示法

querySelector('#confirm') // Get an object.
  ..text = 'Confirm' // Use its members.
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

等同于下面这种写法

var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));

可以嵌套使用

final addressBook = (AddressBookBuilder()
      ..name = 'jenny'
      ..email = '[email protected]'
      ..phone = (PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();

需要注意的是调用级联表达式的时候,所调用的方法不可以返回具体类型,必须返回void。像下面这样就会报错,write方法返回的不是void类型。

var sb = StringBuffer();
sb.write('foo')
  ..write('bar'); // Error: method 'write' isn't defined for 'void'.

其他操作符

() [] . ?.
这里只说下.?他的作用和.差不多,foo?.bar这个表达式表示如果foo不为null的话,取bar的值,否则为null.

控制流

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

循环

var message = StringBuffer('Dart is fun');
for (var i = 0; i < 5; i++) {
  message.write('!');
}

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

var collection = [0, 1, 2];
for (var x in collection) {
  print(x); // 0 1 2
}
while (!isDone()) {
  doSomething();
}
do {
  printLine();
} while (!atEndOfPage());

break 和 continue

和java语言一样。

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

也可以采用流式写法

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

switch语句

case之间不可以省略break。

var command = 'OPEN';
switch (command) {
  case 'OPEN':
    executeOpen();
    // ERROR: Missing break

  case 'CLOSED':
    executeClosed();
    break;
}

可以下面这样写

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

如果你真的想要第一种写法,可以像下面这样使用continue

var command = 'CLOSED';
switch (command) {
  case 'CLOSED':
    executeClosed();
    continue nowClosed;
  // Continues executing at the nowClosed label.

  nowClosed:
  case 'NOW_CLOSED':
    // Runs for both CLOSED and NOW_CLOSED.
    executeNowClosed();
    break;
}

Assert

assert里面的表达式为false时会抛出异常

// 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'));

异常

抛出一个异常

throw FormatException('Expected at least 1 section');

也可以抛出任意对象

throw 'Out of llamas!';

catch

可以只catch指定的异常,或者所有异常,或者不指定类型,捕获抛出的一切。

try {
  breedMoreLlamas();
} on OutOfLlamasException {
  buyMoreLlamas();
}
try {
  breedMoreLlamas();
} on OutOfLlamasException {
  // A specific exception
  buyMoreLlamas();
} on Exception catch (e) {
  // Anything else that is an exception
  print('Unknown exception: $e');
} catch (e) {
  // No specified type, handles all
  print('Something really unknown: $e');
}

也可以使用2个参数的,第一个参数标识异常,第二个参数是StackTrace对象

try {
  // ···
} on Exception catch (e) {
  print('Exception details:\n $e');
} catch (e, s) {
  print('Exception details:\n $e');
  print('Stack trace:\n $s');
}

使用rethrow重新抛出异常

void misbehave() {
  try {
    dynamic foo = true;
    print(foo++); // Runtime error
  } catch (e) {
    print('misbehave() partially handled ${e.runtimeType}.');
    rethrow; // Allow callers to see the exception.
  }
}

void main() {
  try {
    misbehave();
  } catch (e) {
    print('main() finished handling ${e.runtimeType}.');
  }
}

finlly

try {
  breedMoreLlamas();
} finally {
  // Always clean up, even if an exception is thrown.
  cleanLlamaStalls();
}
try {
  breedMoreLlamas();
} catch (e) {
  print('Error: $e'); // Handle the exception first.
} finally {
  cleanLlamaStalls(); // Then clean up.
}

总结

语法上和java非常类似,有过编程经验的人很快就能学会了。

你可能感兴趣的:(Dart语法超光速入门(3):操作符与控制流)