前言
笔者在之前已经写了2篇Dart的基础文章了。
Dart 基础 (一)
Dart 基础 (二)
本文是Dart基础的第3篇,在本文中,笔者会主要介绍2部分内容,运算符和异常。
1 Operator(运算符)主要分如下4部分
- 1.1 算数运算符
- 1.2 级联运算符
- 1.3 类型判定运算符
- 1.4 其他运算符
2 异常主要分如下4部分
- 2.0 Try
- 2.1 Throw
- 2.2 Catch
- 2.3 Finally
详情如下:
Dart中可能遇到的运算符如下图所示:
运算符.png上述运算符中,笔者不大熟悉的运算符有:
- 算数运算符:
~/
- 赋值运算符:
??
- 级联运算符:
..
- 类型判定运算符:
as
、is
、is!
- 其他运算符:
?.
如果你对其他运算符不大熟悉,可以查看Dart文档。
1.1 算数运算符
-
~/
: 整除;
整除的结果是 运算符左侧的数 除以 运算符右侧的数 可以商几。
5 ~/ 2 = 2;
7 ~/ 3 = 2;
9 ~/ 3 = 0;
- 赋值运算符:
??
String qiShare1 = 'qiShare1';
String qiShare2;
qiShare2 ??= qiShare1;
print(qiShare2);
// 输出结果
qiShare1
1.2 级联运算符
- 级联运算符:
..
..
级联运算符
class QiCascade {
String firstProperty;
String secondProperty;
String thirdProperty;
String fourthProperty;
}
class QiSubCascade extends QiCascade{
}
void main() {
QiCascade cascade = QiCascade();
cascade.firstProperty = 'firstPropertyValue';
cascade.secondProperty = 'secondPropertyValue';
cascade.thirdProperty = 'thirdPropertyValue';
cascade.fourthProperty = 'fourthPropertyValue';
print('输出属性:${cascade..firstProperty
..secondProperty
..thirdProperty
..fourthProperty}');
print('级联输出:');
print(cascade..firstProperty..secondProperty..thirdProperty..fourthProperty);
print('属性:${cascade.firstProperty}');
print(cascade.firstProperty);
print(cascade.secondProperty);
print(cascade.thirdProperty);
print(cascade.fourthProperty);
cascade..firstProperty = 'changedFirstPropertyValue'
..secondProperty = 'changedSecondPropertyValue'
..thirdProperty = 'changedThirdPropertyValue'
..fourthProperty = 'changedFourthPropertyValue';
print('级联输出:${cascade..firstProperty
..secondProperty
..thirdProperty
..fourthProperty}');
}
输出结果
flutter: 输出属性:Instance of 'QiCascade'
flutter: 级联输出:
flutter: Instance of 'QiCascade'
flutter: 属性:firstPropertyValue
flutter: firstPropertyValue
flutter: secondPropertyValue
flutter: thirdPropertyValue
flutter: fourthPropertyValue
flutter: 级联输出:Instance of 'QiCascade'
看起来级联运算符可以用于同时操作并列的实例变量。
1.3 类型判定运算符
- 类型判定运算符:
as
、is
、is!
操作符 | 解释 |
---|---|
as | 类型转换 |
is | 如果对象是指定的类型返回true |
is! | 如果对象是指定的类型返回false |
dynamic subCascade = QiSubCascade();
if (subCascade is QiCascade) {
subCascade.firstProperty = 'isQiCascadeFirstPropertyValue';
}
print('subCascade属性:${subCascade.firstProperty}');
print('subCascade runtimeType:${subCascade.runtimeType}');
if(subCascade.runtimeType == QiSubCascade) {
print('subCascade的runtimeType为 ${subCascade.runtimeType}');
}
(subCascade as QiCascade).firstProperty = 'asQiCascadeFirstPropertyValue';
print('subCascade属性:${subCascade.firstProperty}');
使用 is 和 as 的区别在于:
- 使用is:如果上述subCascade不是QiCascade,则条件中的赋值代码不会执行
- 使用as:如果上述subCascade为null 或者不是QiCascade类型,则运行过程中会抛出异常。
输出结果
flutter: subCascade属性:isQiCascadeFirstPropertyValue
flutter: subCascade runtimeType:QiSubCascade
flutter: subCascade的runtimeType为 QiSubCascade
flutter: subCascade属性:asQiCascadeFirstPropertyValue
1.4 其他运算符
运算符 | 名字 | 解释 |
---|---|---|
() | 使用方法 | 代表调用一个方法。 |
[] | 访问List | 访问list 中特定位置的元素。 |
. | 访问Member | 访问元素,如上边我们访问cascade.firstProperty。 |
?. | 条件成员访问 | 和 . 类型, 但是.左边操作对象不能为null,否则抛出异常,?.左边的操作对象可以为null,返回null。 |
subCascade = null;
try {
print('赋值null 后访问成员 ${subCascade.firstProperty}');
} catch (e) {
print('异常信息 $e');
}
print('赋值null 后访问成员 ${subCascade?.firstProperty}');
输出结果
flutter: 异常信息 NoSuchMethodError: The getter 'firstProperty' was called on null.
Receiver: null
Tried calling: firstProperty
flutter: 赋值null 后访问成员 null
如果我们使用条件成员访问运算符?.
。就不会有上述异常。
-
其他运算符:
?.
: 条件成员访问,如果操作符左侧的实例存在,则会取值 ;如qiShare?.name,如果qiShare 不为null,则返回结果为qiShare.name。否则返回结果为null。
subCascade = null;
subCascade ?. firstProperty;
异常
常见的异常有 FormatException格式异常、HttpException网络异常、FileSystemException操作文件的异常、越界的异常,操作的实例调用了没有实现的方法 的异常。
2.1 Try
try 用于包含可能出现异常的代码
2.2 Throw
throw 用于抛出异常。
2.3 Catch
Catch 用于捕获异常,可以防止异常继续传递。除非使用了rethrow
会将捕获的异常再次抛出。
笔者先举了2个特定的异常例子FormatException 、IntegerDivisionByZeroException
1.FormatException,在把字符串'123�4B'转为数字的时候出现的类型转换异常。
var numValue = '123�4B';
try {
int numValueInt = int.parse(numValue);
print(numValueInt);
} on FormatException catch (e){
print('出现FormatException: $e');
// rethrow; 使用rethrow 会将catch 住的异常再次抛出
} on Exception catch(e) {
print('Exception: $e');
// rethrow; 使用rethrow 会将catch 住的异常再次抛出
}
// 输出结果:
/*
flutter: 出现FormatException: FormatException: Invalid radix-10 number (at character 1)
123\^]4B
*/
2.IntegerDivisionByZeroException 在0作除数的时候出现的异常。整除出现。
// double zeroValue = 0.0; // 如果使用0.0 则IntegerDivisionByZeroException 不会捕获
int zeroValue = 0;
int num1 = 1;
try {
print(num1 ~/ zeroValue); // 会触发异常 但是也不是除0异常
// print(num1 / zeroValue); // 不会触发异常
} on IntegerDivisionByZeroException catch(e) {
print('除以0异常:$e');
} catch (e) {
print('异常信息:$e');
}
// 输出结果
flutter: 除以0异常:IntegerDivisionByZeroException
下边笔者又列举了其他的几个异常的例子。
// 抛出异常示例
try {
throw Exception(
'Custom Exception'
);
} catch (e) {
print(e);
}
try {
throw '自定义字符串Exception';
} catch (e) {
print(e);
}
List list1 = ['QiShare'];
try {
print(list1[1]);
} catch (e) {
print(e);
}
try {
(list1 as QiCascade).firstProperty;
} catch (e) {
print(e);
}
list1 = null;
try {
print(list1[1]);
} catch (e) {
print(e);
}
try {
(list1 as QiCascade).firstProperty;
} catch (e) {
print(e);
}
输出结果
flutter: Exception: Custom Exception
flutter: 自定义字符串Exception
flutter: RangeError (index): Invalid value: Only valid value is 0: 1
flutter: type 'List<dynamic>' is not a subtype of type 'QiCascade' in type cast
flutter: NoSuchMethodError: The method '[]' was called on null.
Receiver: null
Tried calling: [](1)
flutter: NoSuchMethodError: The getter 'firstProperty' was called on null.
Receiver: null
Tried calling: firstProperty
针对上述代码的异常捕获,笔者发现,catch不仅可以捕获异常也可以捕获Error,笔者Dart 的Exceptions 包括Exception 和 Error。并且对如上代码中RangeError、NoSuchMethodError的代码做了如下处理:
捕获RangeError
List list1 = ['QiShare'];
try {
print(list1[1]);
} on RangeError catch(error) {
print('RangeError错误:$error');
} catch (e) {
print(e.runtimeType);
print(e);
}
// 输出结果:
/*
flutter: RangeError错误:RangeError (index): Invalid value: Only valid value is 0: 1
*/
捕获NoSuchMethodError
List list1;
try {
print(list1[1]);
} on NoSuchMethodError catch(noSuchMethodError){
print('NoSuchMethodError错误:$noSuchMethodError');
} catch (e) {
print('异常信息:$e');
}
// 输出结果:
/**
* flutter: NoSuchMethodError错误:NoSuchMethodError: The method '[]' was called on null.
Receiver: null
Tried calling: [](1)
*/
2.4 Finally
Finally 部分的代码,不管是否有出现异常,都会执行,如果出现了异常,则执行完catch中的代码后,会执行Finally 中的代码,如果没有出现异常,则执行完了try中的代码后,会执行Finally 中的代码。
List list1;
try {
print(list1[1]);
} on NoSuchMethodError catch(noSuchMethodError){
print('NoSuchMethodError错误:$noSuchMethodError');
} catch (e) {
print('异常信息:$e');
} finally {
print('执行Finally 中的代码');
}
/**
* flutter: NoSuchMethodError错误:NoSuchMethodError: The method '[]' was called on null.
Receiver: null
Tried calling: [](1)
flutter: 执行Finally 中的代码
*/
还有一种情况是try 中的代码出现了异常,但是没有使用catch 进行异常捕获。但使用了finally 语句。像这种情况,出现异常的情况下,会先执行finally 中的代码,然后抛出异常。
代码如下:
List list3;
try {
print(list3[1]);
} finally {
print('执行Finally 中的代码');
}
// 输出结果:
/**
flutter: 执行Finally 中的代码
flutter: ══╡ EXCEPTION CAUGHT BY GESTURE ╞═══════════════════════════════════════════════════════════════════
flutter: The following NoSuchMethodError was thrown while handling a gesture:
flutter: The method '[]' was called on null.
flutter: Receiver: null
flutter: Tried calling: [](1)
flutter:
flutter: When the exception was thrown, this was the stack:
flutter: #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:50:5)
省略............
*/
网友评论