美文网首页
Dart 基础 (三)

Dart 基础 (三)

作者: Lucky_Man | 来源:发表于2019-07-11 21:54 被阅读0次

    前言
    笔者在之前已经写了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

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

    • 算数运算符:~/
    • 赋值运算符:??
    • 级联运算符:..
    • 类型判定运算符: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,在把字符串'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)
    省略............
        */
    

    参考学习网址

    相关文章

      网友评论

          本文标题:Dart 基础 (三)

          本文链接:https://www.haomeiwen.com/subject/mevjkctx.html