# 运算符和控制流程语句
# 运算符
# 算术运算符
操作符 | 含义 |
---|---|
+ | 加法 |
- | 减法 |
* | 乘法 |
/ | 除法 |
~/ | 除法,返回整数结果 |
% | 除法,获取余数(取模) |
++var | 自增,先增再运算 |
var++ | 自增,先运算再增 |
--var | 自减,先减再运算 |
var-- | 自减,先运算再减 |
print(1+2); // 3
print(1-2); // -1
print(2*3); // 6
print(7/2); // 3.5
print(7~/2); // 3
print(7%2); // 1
var n = 2;
print(n++); // 2
print(n); // 3
print(--n); // 2
# 关系运算符
操作符 | 含义 |
---|---|
== | 等于 |
!= | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
要判断两个对象是否表示相同的事物,使用 ==
运算符(有时,要确定两个对象是否完全相同,用identical()
函数)
print(2 == 2);
print(3 != 2);
print(3 > 2);
print(2 < 3);
print(2 >= 2);
print(2 <= 2);
# 类型判定运算符
操作符 | 含义 |
---|---|
as | 类型转换 |
is | 如果对象具有指定的类型则为true |
is! | 如果对象具有指定的类型则为false |
这几个运算符用于在运行时处理类型检查
void main(){
var p = new Person('zhangsan');
assert(p is Person);
var s = new Student(12);
assert(s is Student);
if(p is Person){
print(p.name);
}
}
class Person {
String name;
Person(this.name);
}
class Student {
int age;
Student(this.age);
}
其中
if(p is Person){
print(p.name);
}
可以变成
print((p as Person).name);
但是这两者并不是相等的,因为在第二种情况中,如果p不是Person的实例,那么是会抛出异常的
# 赋值运算符
使用=
为变量赋值
var a = 1;
使用??=
运算符,当被赋值的变量为null时才会赋值给它,否则还是原本的值
var a = 1;
var b = 2;
var c;
b ??= a;
c ??= a;
print(b); // 2
print(c); // 1
# 逻辑运算符
操作符 | 含义 |
---|---|
&& | 与,两个都成立则成立 |
|| | 或,只要有一个成立就成立 |
! | 非,将表达式反转,true变成false, false变成true |
这个和其他的语言基本一样
# 条件表达式
操作符 | 含义 |
---|---|
condition ? expr1 : expr2 | 三目运算符,如果condition为true,则执行expr1,否则执行expr2 |
expr1 ?? expr2 | 如果expr1是null,则返回expr2的值,否则返回expr1的值 |
var f = false;
var a = f ? 'Yes' : 'No';
print(a); // No
var n = null;
print(n ?? 666); // 666
# 级联运算符
实现对同一个对象进行一系列操作.除了调用函数,还能访问字段属性,有点像jQuery的链式调用.好处是可以节省创建临时变量的步骤,使编写出来的代码更加的流畅.
List<int> list = [1,2]
..add(3)
..add(4);
print(list); // [1, 2, 3, 4]
# 其他运算符
如 ?.
当运算符左边不为null的时候,获取其运算符右边的属性值.当为null时,返回null
var p = new Person('zhangsan');
var p2 = null;
print(p?.name); // zhangsan
print(p2?.name); // null
# 控制流程语句
顾名思义,就是用来控制dart程序流程走向的语句
# if和else
var a = 2;
if(a == 1){
print(1);
}else if(a == 2){
print(2);
}else{
print(3);
}
# for循环
var list = ['zhangsan','lis'];
for(var i = 0; i < list.length; i++) {
print(list[i]);
}
如果要迭代一个实现了 Iterable
接口的对象,可以使用forEach()方法 ,例如 List, Set 等
var list = ['zhangsan','lis'];
list.forEach((item) => print(item));
var s = {'zhangsan','lisi'};
s.forEach((item) => print(item));
同样的,它们也支持使用 for-in
来进行迭代
var s = {'zhangsan','lisi'};
for(var p in s){
print(p);
}
# while和do-while
和其他语言的基本一样,while就是先判断再执行, do-while就是先执行再判断
var a = 1;
while(a < 5){
print(a++); // 1 2 3 4
}
var b = 1;
do{
print(b++); // 1
}while(b < 1);
# break和continue
和其他语言的基本一样,break停止循环,continue跳转到下次迭代
for(var i = 0; i < 5; i++){
if(i == 2){
break;
}
print(i); // 0 1
}
for(var i = 0; i < 5; i++){
if(i == 2){
continue;
}
print(i); // 0 1 3 4
}
# switch和case
每个非空的case语句结尾必须要跟一个break语句.除break以外还有continue, throw , return,否则会报错
var a = 1;
switch(a){
case 1:
print(1);
break;
case 2:
print(2);
default:
print('other');
}
上面的代码会报错:Error: Switch case may fall through to the next case.
若匹配到某一个为空的case语句,则顺延执行下一个case语句,下面的代码打印出other
var a = 2;
switch(a){
case 1:
print(1);
break;
case 2:
default:
print('other');
}
可以使用continue语句跳转到具体的一个标签处
var a = 2;
switch(a){
label:
case 1:
print(1);
break;
case 2:
print(2);
continue label;
default:
print('other');
}
# assert
断言语句,生产环境无效,只在开发环境中有效 可以有两个参数: 第一个参数是一个解析成bool类型的任何表达式.若为true,断言成功,程序继续执行,若为false,断言失败,抛出异常 第二个参数就是断言失败抛出异常时的自定义提示
var a = 1;
assert(a == 1);
assert(a != 1,'a的值为1,所以此次断言失败');