前言
本篇文章参考自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非常类似,有过编程经验的人很快就能学会了。