Dart语言基础之运算符
Dart运算符定义了下表中的运算符。你可以重载它们中的许多运算符,Overridable operators.
Description | Operator |
---|---|
unary postfix |
*expr*++ *expr*-- () [] . ?.
|
unary prefix |
-*expr* !*expr* ~*expr* ++*expr* --*expr*
|
multiplicative |
* / % ~/
|
additive |
+ -
|
shift |
<< >> >>>
|
bitwise AND | & |
bitwise XOR | ^ |
bitwise OR | | |
relational and type test |
>= > <= < as is is!
|
equality |
== !=
|
logical AND | && |
logical OR | || |
if null | ?? |
conditional | *expr1* ? *expr2* : *expr3* |
cascade | .. |
assignment |
= *= /= += -= &= ^= etc.
|
Warning: 运算符优先级是Dart解析器行为的近似值。Dart language specification.
当你使用运算符创建表达式。下面是一些运算符表达式的例子:
a++
a + b
a = b
a == b
c ? a : b
a is T
在运算符表中的运算符,优先级按照行的从上到下递减。
对于有两个操作数的运算符,左操作决定了运算符的运算,例如,一个
Vector
对象和一个Point
对象aVector + aPoint
进行的是Vector的+运算。
算术运算符
Dart 支持寻常的算数运算符。
Operator | Meaning |
---|---|
+ | Add |
– | Subtract |
-expr | Unary minus, also known as negation (reverse the sign of the expression) |
* | Multiply |
/ | Divide |
~/ | Divide, returning an integer result |
% | Get the remainder of an integer division (modulo) |
Dart 也支持前缀和后缀增加或减少
Operator | Meaning |
---|---|
++var | var = var + 1 (expression value is var + 1) |
var++ | var = var + 1 (expression value is var) |
--var | var = var – 1 (expression value is var – 1) |
var-- | var = var – 1 (expression value is var) |
关系运算符
Operator | Meaning |
---|---|
== | Equal; see discussion below |
!= | Not equal |
> | Greater than |
< | Less than |
>= | Greater than or equal to |
<= | Less than or equal to |
为了测试两个对象是不是一样的东西, ==
. (在极少情况下要确定两个对象是否same使用 identical() 方法.) ==
原理:
-
If x or y is null, return true if both are null, and false if only one is null.
-
Return the result of the method invocation
x.==(y)
. (That’s right, operators such as==
are methods that are invoked on their first operand. You can even override many operators, including==
, as you’ll see in Overridable operators.)
类型测试运算符
as
, is
, and is!
可以在运行时方便的检查类型.
Operator | Meaning |
---|---|
as |
Typecast (also used to specify library prefixes) |
is |
True if the object has the specified type |
is! |
False if the object has the specified type |
obj is T
返回真如果obj
实现了接口 T
. 例如, obj is Object
永远为真.
用 as
运算符把对象强制转换为特殊类型. 在多数情况下,亦可以把它用作is
后使用这个对象的简写:
if (emp is Person) {
// Type check
emp.firstName = 'Bob';
}
你可以用 as
缩短代码:
(emp as Person).firstName = 'Bob';
Note: 上面两种代码并不等效. 若emp
为null
或不是 Person, 第一个例子什么都不做; 第二个会抛异常.
赋值运算符
用=
给变量赋值,??==
仅当变量为null
时才赋值
// Assign value to a
a = value;
// Assign value to b if b is null; otherwise, b stays the same
b ??= value;
复合赋值运算符
= | –= | /= | %= | >>= | ^= |
+= | *= | ~/= | <<= | &= | = |
复合赋值运算符原理:
For an operator op: | a op= b | a = a op b |
Example: | a += b | a = a + b |
var a = 2; // Assign using =
a *= 3; // Assign and multiply: a = a * 3
assert(a == 6);
逻辑运算符
Operator | Meaning |
---|---|
!*expr* |
inverts the following expression (changes false to true, and vice versa) |
|| |
logical OR |
&& |
logical AND |
if (!done && (col == 0 || col == 3)) {
// ...Do something...
}
位运算操作符
Operator | Meaning |
---|---|
& |
AND |
| |
OR |
^ |
XOR |
~*expr* |
Unary bitwise complement (0s become 1s; 1s become 0s) |
<< |
Shift left |
>> |
Shift right |
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
条件运算符
Dart有两个运算符,可以让您简明地计算可能需要 if-else语句的表达式:
condition ? expr1 : expr2
If condition is true, evaluates expr1 (and returns its value); otherwise, evaluates and returns the value of expr2.
expr1 ?? expr2
If expr1 is non-null, returns its value; otherwise, evaluates and returns the value of expr2.
When you need to assign a value based on a boolean expression, consider using ?:
.
var visibility = isPublic ? 'public' : 'private';
If the boolean expression tests for null, consider using ??
.
String playerName(String name) => name ?? 'Guest';
The previous example could have been written at least two other ways, but not as succinctly:
// 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 notation (..)
Cascades (..
) allow you to make a sequence of operations on the same object. In addition to function calls, you can also access fields on that same object. This often saves you the step of creating a temporary variable and allows you to write more fluid code.
Consider the following code:
querySelector('#confirm') // Get an object.
..text = 'Confirm' // Use its members.
..classes.add('important')
..onClick.listen((e) => window.alert('Confirmed!'));
The first method call, querySelector()
, returns a selector object. The code that follows the cascade notation operates on this selector object, ignoring any subsequent values that might be returned.
The previous example is equivalent to:
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
You can also nest your cascades. For example:
final addressBook = (AddressBookBuilder()
..name = 'jenny'
..email = 'jenny@example.com'
..phone = (PhoneNumberBuilder()
..number = '415-555-0100'
..label = 'home')
.build())
.build();
Be careful to construct your cascade on a function that returns an actual object. For example, the following code fails:
var sb = StringBuffer();
sb.write('foo')
..write('bar'); // Error: method 'write' isn't defined for 'void'.
The sb.write()
call returns void, and you can’t construct a cascade on void
.
Note: Strictly speaking, the “double dot” notation for cascades is not an operator. It’s just part of the Dart syntax.
其他运算符
Operator | Name | Meaning |
---|---|---|
() |
Function application | Represents a function call |
[] |
List access | Refers to the value at the specified index in the list |
. |
Member access | Refers to a property of an expression; example: foo.bar selects property bar from expression foo
|
?. |
Conditional member access | Like . , but the leftmost operand can be null; example: foo?.bar selects property bar from expression foo unless foo is null (in which case the value of foo?.bar is null) |
For more information about the .
, ?.
, and ..
operators, see Classes.