运算符
算术运算符
~/ 是整除运算符
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);
类型测试运算符
(emp as Person).firstName = 'Bob';
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
赋值运算符
// Assign value to a
a = value;
// Assign value to b if b is null; otherwise, b stays the same
b ??= value;
var a = 2; // Assign using =
a *= 3; // Assign and multiply: a = a * 3
assert(a == 6);
位运算符
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
条件运算符
var visibility = isPublic ? 'public' : 'private';
String playerName(String name) => name ?? 'Guest';
// Slightly longer version uses ?: operator.
String playerName(String name) => name != null ? name : 'Guest';
// Very long version uses if-else statement.
String playerName(String name) {
if (name != null) {
return name;
} else {
return 'Guest';
}
}
层叠(Cascade)记叙
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 = 'jenny@example.com'
..phone = (PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build())
.build();
// 注意方法必须返回同一个对象
var sb = StringBuffer();
sb.write('foo')
..write('bar'); // Error: method 'write' isn't defined for 'void'.
其他运算符
控制语句
if else 语句
// if else
if (isRaining()) {
you.bringRainCoat();
} else if (isSnowing()) {
you.wearJacket();
} else {
car.putTopDown();
}
for 循环
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()); // 0 1
// Iterable 类型的 forEach 方法
candidates.forEach((candidate) => candidate.interview());
// for in 循环
var collection = [0, 1, 2];
for (var x in collection) {
print(x); // 0 1 2
}
while do-while break continue
// while 循环
while (!isDone()) {
doSomething();
}
// do-while 循环
do {
printLine();
} while (!atEndOfPage());
// 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();
}
// 改用 Iterable 类型 的方法调用
candidates
.where((c) => c.yearsExperience >= 5)
.forEach((c) => c.interview());
switch 语句
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();
}
// switch 语句中的 case 子句不能省略 break
var command = 'OPEN';
switch (command) {
case 'OPEN':
executeOpen();
// ERROR: Missing break
case 'CLOSED':
executeClosed();
break;
}
// switch 语句中的 case 子句可以为空
var command = 'CLOSED';
switch (command) {
case 'CLOSED': // Empty case falls through.
case 'NOW_CLOSED':
// Runs for both CLOSED and NOW_CLOSED.
executeNowClosed();
break;
}
// 使用 continue 来实现 fall-through
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 语句
// 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(urlString.startsWith('https'),
'URL ($urlString) should start with "https".')
异常
throw 语句
throw FormatException('Expected at least 1 section');
throw 'Out of llamas!';
void distanceTo(Point other) => throw UnimplementedError();
捕获异常 try on 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');
}
// catch 带两个参数,异常和调用栈 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}.');
}
}
finally
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.
}