Dart编程语言从基础到进阶7

运算符在编程语言中也是很重要的一环,如果有其他语言基础的话看这一节会很轻松,但是也要特别注意一些运算符,因为它跟其他语言还是有点差别的。

在运算符表 中,运算符的优先级按先后排列,即第一行优先级最高,最后一行优先级最低,而同一行中,最左边的优先级最高,最右边的优先级最低。

描述 运算符
一元后缀 表达式++ 表达式-- () [] . ?.
一元前缀 -表达式 !表达式 ~表达式 ++表达式 --表达式
乘除法 * / % ~/
加减法 + -
位运算 << >> >>>
二进制与 &
二进制异或 ^
二进制或 |

关系和类型测试 >= > <= < as is is!
相等判断 == !=
逻辑与 &&
逻辑或 ||
空判断 ??
条件表达式 表达式 1 ? 表达式 2 : 表达式 3
级联 …
赋值 = *= /= += -= &= ^= 等等……

一旦你使用了运算符,就创建了表达式。

a++
a + b
a = b
a == b
c ? a : b
a is T
// 括号提高了可读性。
if ((n % i == 0) && (d % i == 0)) ...
// 难以理解,但是与上面的代码效果一样。
if (n % i == 0 && d % i == 0) ...

算术运算符

Dart 支持常用的算术运算符:

描述 运算符
+ 表达式++ 表达式-- () [] . ?.
-表达式 一元负, 也可以作为反转(反转表达式的符号)
*
/
~/ 除并取整
% 取模

示例:

assert(2 + 3 == 5);
assert(2 - 3 == -1);
assert(2 * 3 == 6);
assert(5 / 2 == 2.5); // 结果是一个浮点数
assert(5 ~/ 2 == 2); // 结果是一个整数
assert(5 % 2 == 1); // 取余


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

Dart 还支持自增自减操作。

++var
var = var + 1 (表达式的值为 var + 1)

var++	var = var + 1 (表达式的值为 var)

--var	var = var – 1 (表达式的值为 var – 1)

var--	var = var – 1 (表达式的值为 var)

示例:

var a, b;


a = 0;
b = ++a; // 在 b 赋值前将 a 增加 1。
assert(a == b); // 1 == 1


a = 0;
b = a++; // 在 b 赋值后将 a 增加 1。
assert(a != b); // 1 != 0


a = 0;
b = --a; // 在 b 赋值前将 a 减少 1。
assert(a == b); // -1 == -1


a = 0;
b = a--; // 在 b 赋值后将 a 减少 1。
assert(a != b); // -1 != 0


关系运算符

== 相等
!=  不等
>  大于
<  小于
>=  大于等于
<=  小于等于

要判断两个对象 x 和 y 是否表示相同的事物使用 == 即可。

== 运算符的一些规则:

1.假设有变量 x 和 y,且 x 和 y 至少有一个为 null,则当且仅当 x 和 y 均为 null 时 x == y 才会返回 true,否则只有一个为 null 则返回 false。

2.x.==(y) 将会返回值,这里不管有没有 y,即 y 是可选的。也就是说 == 其实是 x 中的一个方法,并且可以被重写。

下面的代码给出了每一种关系运算符的示例:

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

类型判断运算符

as   //类型转换(也用作指定类前缀))
is   //如果对象是指定类型则返回 true
is!  //如果对象是指定类型则返回 false

当且仅当 obj 实现了 T 的接口,obj is T 才是 true。例如 obj is Object 总为 true,因为所有类都是 Object 的子类。

使用 as 操作符可以把对象转换为特定的类型。一般情况下可以将其当做 is 判定类型后调用所判定对象的函数的缩写形式。假设有如下代码:

if (emp is Person) {
  // 类型检查
  emp.firstName = 'Bob';
}

你可以使用 as 运算符进行缩写:

(emp as Person).firstName = 'Bob';

tips:上述两种方式是有区别的:如果 emp 为 null 或者不为 Person 类型,则第一种方式最多只是不执行条件内代码,但是第二种方式则会抛出异常。

赋值运算符

可以使用 = 来赋值,同时也可以使用 ??= 来为值为 null 的变量赋值。

// 将 value 赋值给 a
a = value;
// 当且仅当 b 为 null 时才赋值
b ??= value;

像 += 这样的赋值运算符将算数运算符和赋值运算符组合在了一起。


=  –=  /=  %=  >>=  ^=
+=  *=  ~/=  <<=  &=  |=

下表解释了符合运算符的原理:

场景 复合运算 等效表达式
假设有运算符 op: a op= b a = a op b
示例: a += b a = a + b

下面的例子展示了如何使用赋值以及复合赋值运算符:

var a = 2; // 使用 = 赋值
a *= 3; // 赋值并做乘法运算:a = a * 3
assert(a == 6);

逻辑运算符

使用逻辑运算符你可以反转或组合布尔表达式。

运算符	描述
!!表达式	对表达式结果取反(即将 true 变为 false,false 变为 true)
||	逻辑或
&&	逻辑与

下面是使用逻辑表达式的示例:

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

按位和移位运算符

在 Dart 中,二进制位运算符可以操作二进制的某一位,但仅适用于整数。

运算符	描述
&	按位与
|	按位或
^	按位异或
~表达式	按位取反
<<	左位移
>>	右位移

下面是使用按位和移位运算符的示例:

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


assert((value & bitmask) == 0x02); // 按位与
assert((value & ~bitmask) == 0x20); // 取反后按位与
assert((value | bitmask) == 0x2f); // 按位或
assert((value ^ bitmask) == 0x2d); // 按位异或
assert((value << 4) == 0x220); // 位左移
assert((value >> 4) == 0x02); // 位右移

条件表达式

Dart 有两个特殊的运算符可以用来替代 if-else 语句:

condition ? expr1 : expr2 //条件 ? 表达式 1 : 表达式 2:如果条件为 true,执行表达式 1并返回执行结果,否则执行表达式 2 并返回执行结果。

expr1 ?? expr2表达式 1 ?? 表达式 2:如果表达式 1 为非 null 则返回其值,否则执行表达式 2 并返回其值。

如果赋值是根据布尔表达式则考虑使用 ?:。

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

如果赋值是根据判定是否为 null 则考虑使用 ??。

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

上述示例还可以写成至少下面两种不同的形式,只是不够简洁:

// 相对使用 ?: 运算符来说稍微长了点。
String playerName(String name) => name != null ? name : 'Guest';
// 如果使用 if-else 则更长。
String playerName(String name) {
  if (name != null) {
    return name;
  } else {
    return 'Guest';
  }
}

级联运算符(…)

级联运算符(…)可以让你在同一个对象上连续调用多个对象的变量或方法。

比如下面的代码:

querySelector('#confirm') // 获取对象。
  ..text = 'Confirm' // 使用对象的成员。
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

第一个方法 querySelector 返回了一个 Selector 对象,后面的级联操作符都是调用这个 Selector 对象的成员并忽略每个操作的返回值。

上面的代码相当于:

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();

在返回对象的函数中谨慎使用级联操作符。例如,下面的代码是错误的:

var sb = StringBuffer();
sb.write('foo')
  ..write('bar'); // 出错:void 对象中没有方法 write。

上述代码中的 sb.write() 方法返回的是 void,返回值为 void 的方法则不能使用级联运算符。

tips:严格来说 … 级联操作并非一个运算符而是 Dart 的特殊语法。结语:

最近在录制视频,到时候也会免费放在公众号中供大家学习交流使用。如果对您有用请关注,如果文中有错也欢迎指正。共同学习,共同进步。

原创文章 52 获赞 40 访问量 9万+

猜你喜欢

转载自blog.csdn.net/farley119/article/details/103374689
今日推荐