likes
comments
collection
share

Dart基础(三)

作者站长头像
站长
· 阅读数 0

级别: ★☆☆☆☆ 标签:「Flutter 」「Dart」「Dart Operator」「Dart Exceptions」 作者: WYW 审校: QiShare团队


前言 笔者在之前已经写了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中可能遇到的运算符如下图所示:

Dart基础(三)

上述运算符中,笔者不大熟悉的运算符有:

  • 算数运算符:~/
  • 赋值运算符:??
  • 级联运算符:..
  • 类型判定运算符:asisis!
  • 其他运算符:?.

如果你对其他运算符不大熟悉,可以查看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 类型判定运算符

  • 类型判定运算符:asisis!
操作符解释
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,在把字符串'1234B'转为数字的时候出现的类型转换异常。

var numValue = '1234B';
    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)
省略............
    */

参考学习网址


推荐文章: Dart基础(一) Dart基础(二) iOS 短信验证码倒计时按钮 iOS 环境变量配置 iOS 中处理定时任务的常用方法 算法小专栏:贪心算法 iOS 快速实现分页界面的搭建 iOS 中的界面旋转 奇舞周刊