Dart(二)--函数&运算符&条件语句&异常

上篇介绍了Dart如何定义变量,以及它的内置类型,这篇将介绍如何定义函数、各类运算符、条件语句

一、函数

Dart的函数和kotlin类似,也是一个对象,函数既可以作为参数传递,也可以作为返回参数

1.定义函数

Dart定义函数的规则为:[返回类型] ([参数类型] 参数名, ...){ return 返回值 },可以看出通过Dart的类型推断返回类型参数类型可以省略,但官方还是推荐写全

// 定义一个求和函数
int sum(int a, int b) {
  return a + b;
}

main() {
  print(sum(10, 20));
}
1.1 => 单行表达式

如果你的函数只有一个简单的表达式,可以使用=>代替{}的内容

// 定义一个求和函数
int sum(int a, int b) => a + b;

main() {
  print(sum(10, 20));
}
2.参数

Dart的参数定义很灵活,也有可选参数、参数默认值

2.1 {} 命名参数

除了上面定义函数时必传参数的方式外,Dart也支持可选参数,其中一种为命名参数

命名参数使用{参数1,参数2,...}规则定义,并且需要放置在必传参数后面。调用时非require修饰的可空命名参数可选参数具有默认值可以不传递值,也可以对命名参数使用参数名:进行指定值。命名参数传递时,可以放在任意位置

// 定义一个可选参数的求和函数
int sum(int a, {int? b}) {
  if (b != null) return a + b;
  return a;
}

main() {
  print(sum(10));
  // 指定参数b为10
  print(sum(10, b: 10));
  // 命名参数传递时,可以放在随意的位置
  print(sum(b: 20, 30));
}

运行结果:

如果你想对某个命名参数设置为必填,可以使用require关键字修饰该参数。不过因为定义时已经是可选参数了,所以require的使用场景并不多

// 定义一个可选参数的求和函数
int sum(int a, {required int? b}) {
  if (b != null) return a + b;
  return a;
}

此时不传参数b的值,会报错:

2.2 [] 位置参数

另一种可选参数是位置参数,功能上比命名参数少一点,不能以参数名指定值、不能使用require修饰,不能随意摆放传递参数位置

// 带有前缀的打印
prefixPrint(String info, [String? prefix]) {
  if (prefix != null) return print(prefix + info);
  print(info);
}

main() {
  prefixPrint("info", "hi ");
}
2.3 参数默认值

我们可以对可选参数设置默认值,直接在定义时使用=赋值即可,默认值必须为常量,命名参数require修饰和参数默认值不能同时使用

// 打印信息默认为hi
hiPrint({String info = "hi"}) => print(info);

main() {
  hiPrint(info: "hello");
  hiPrint();
}

运行结果:

// 带有前缀的打印
prefixPrint(String info, [String prefix = ""]) {
  return print(prefix + info);
}

main() {
  prefixPrint("info", "hi ");
  prefixPrint("info");
}

运行结果:

3.函数传递

上边提到过Dart中函数也是一个对象,可以赋值给一个变量,可以作为参数传递

// 定义函数
void hi() => print("hi");

// action参数为一个函数,在打印前,调用一次该函数
void combinePrint(String info, void action()) {
  action();
  print(info);
}

main() {
  // 函数赋值给变量
  var printHi = hi;
  // 调用函数变量
  printHi();

  combinePrint("打印前调用hi函数", hi);
}

运行结果:

4.匿名函数

函数也可以通过匿名方式创建,和定义函数的方式差不多

下面的程序有点无聊,我们定义一个具名函数callFunction,它有三个参数,分别是int型的ab,还有一个接收两个int值参数的函数参数function,我们将callFunctiona,b参数又传递给function函数使用,获取值并打印。

调用callFunction时,我们使用了匿名函数

// 调用函数参数的函数
void callFunction(int a, int b, int function(int a, int b)) {
  // 传入的a,b,传递给function
  var result = function(a, b);
  // 打印结果
  print(result);
}

main() {
  // 传入一个匿名函数    
  callFunction(10, 20, (a, b) {
    return a - b;
  });
}

运行结果:

匿名函数如果只有单行表达式,也支持=>方式定义:

main() {
  // 传入一个匿名函数
  callFunction(10, 20, (a, b) {
    return a - b;
  });

  callFunction(10, 20, (a, b) => a + b);
}

二、运算符

Dart运算符和常规的类似,下面直接列出列表方便快速浏览

1.算术运算符

区别:/是除,返回一个double类型;~/才是取整

运算符描述
+
-
*
/
~/取整
%取模
++数+1,前置返回当前数+1,后置返回当前数
--数-1,前置返回当前数-1,后置返回当前数
2.关系运算符
运算符描述
==相等
!=不等
>大于
<小于
>=大于等于
<=小于等于
3.类型判断运算符
运算符描述
as类型转换(也用作指定 库前缀))
is如果对象是指定类型则返回 true
is!如果对象是指定类型则返回 false
4.赋值运算符
4.1 ??= 可空变量赋值

由于Dart中可空变量的存在,除了直接使用=给非空变量赋值外,还可以使用??=为可空变量赋值,它将在变量为空时执行赋值操作,不为空时不进行赋值

main() {
  int? i;
  i ??= 1;
  i ??= 2;

  print(i);
}

为不是空的可空变量赋值时,会报出一个警告,运行结果:

4.2 其他赋值运算符
运算符描述
=赋值
*=乘后赋值
%=取模后赋值
>>=右移后赋值
>>>=无符号右移后赋值
^=幂后赋值
+=加后赋值
/=除后赋值
<<=左移后赋值
<<<=无符号左移后赋值
&=与后赋值
`=`
-=减后赋值
~/=取整后赋值
5.逻辑运算符
运算符描述
!*表达式*对表达式结果取反(即将 true 变为 false,false 变为 true)
||逻辑或
&&逻辑与
6. 按位和移位运算符
运算符描述
&按位与
|按位或
^按位异或
~*表达式*按位取反(即将 “0” 变为 “1”,“1” 变为 “0”)
<<位左移
>>位右移
>>>无符号右移
7.条件运算符

Dart除了三目运算符,还有空运算符

7.1 条件 ? 表达式1 : 表达式2

条件为 true,执行 表达式1 并返回执行结果,否则执行 表达式2 并返回执行结果。

7.2 表达式1 ?? 表达式2

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

8.级联运算符

级联运算符也是方便对变量进行配置,不过没有kotlin的函数式编程好用

8.1 …

..:同一个对象上连续调用多个对象的变量或方法,使用时注意;只有一个

class P {
  var name;
  var password;
}

main() {
  var p = P()
    ..name = "zhangsan"
    ..password = "123";

  print(p.name);
  print(p.password);
}

运行结果:

8.2 ?..

如果对象可能为空,那么使用?..可以在不为空时才进行操作

class P {
  var name;
  var password;
}

// 返回一个空
P? getP() {}

main() {
  var p = getP()
    ?..name = "zhangsan"
    ..password = "hi";

  print(p);
}

运行结果:

9.其他运算符
运算符名字描述
()使用方法代表调用一个方法
[]访问 List访问 List 中特定位置的元素
?[]判空访问 List左侧调用者不为空时,访问 List 中特定位置的元素
.访问成员成员访问符
?.条件访问成员与上述成员访问符类似,但是左边的操作对象不能为 null,例如 foo?.bar,如果 foo 为 null 则返回 null ,否则返回 bar
!空断言操作符将表达式的类型转换为其基础类型,如果转换失败会抛出运行时异常。例如 foo!.bar,如果 foo 为 null,则抛出运行时异常

三、条件语句

Dart条件语句和Java几乎一样

  • ifelseelse可选
  • for 循环:可迭代对象支持:for(i in iterator)
  • whiledo-while 循环
  • breakcontinue
  • switchcasecase依然需要和break配合,使用 == 来比较整数、字符串或编译时常量
1.assert 断言

断言使用assert(表达式),表达式为true,程序继续执行,否则抛出AssertionError异常。在Flutter中,调试模式断言会起作用,但生产环境代码中,断言会被忽略

四、异常

与 Java 不同的是,Dart 的所有异常都是非必检异常,方法不必声明会抛出哪些异常,并且你也不必捕获任何异常。

1.抛出异常

除了抛出一个具体的 ExceptionError 两种类型的异常:

throw FormatException('Expected at least 1 section');

Dart还可以随意抛出一个对象作为异常:

throw "hi";
2.捕获异常
2.1 catch

常规的try-catch-finally方式:

main() {
  var i;

  try {
    assert(i != null);
  } catch (e) {
    print(e);
  } finally {
    print("finally");
  }

  print("next..");
}

运行结果:

catch还支持第二个参数,第二个参数为栈信息 StackTrace 对象:

main() {
  var i;

  try {
    assert(i != null);
  } catch (e, s) {
    print("Exception:$e");
    // 输出栈信息
    print("Stack :$s");
  } finally {
    print("finally");
  }

  print("next..");
}

运行结果:

2.2 on

如果你不关心异常对象,那么可以使用on指定是什么异常类型

main() {
  try {
    throw FormatException("too later");
  } on FormatException {
    print("太晚了");
  }
}

运行结果:

当然也可以和catch组合使用:

main() {
  try {
    throw FormatException("too later");
  } on FormatException catch (e) {
    print("太晚了");
    print(e);
  } on Exception {
    print("Exception");
  }
}

运行结果:

3.重新抛出

rethrow可以将异常再次抛出

main() {
  try {
    throw FormatException("too later");
  } catch (e) {
    print(e);
    rethrow;
  }
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值