美文网首页程序设计
[Flutter]flutter基础之Dart语言基础(二)

[Flutter]flutter基础之Dart语言基础(二)

作者: 陌问MW | 来源:发表于2020-02-20 17:55 被阅读0次

    一、运算符

    Dart 中,支持各种类型运算符,且其中的一些操作符还支持重载操作。

    1. 算数运算符

    Dart 中的算数运算符有以下几种:+-*/%~/ ,通过以下示例说明:

    main(){  
      var a = 21;
      var b = 10;
      var c;
    
      c = a + b;  //加法操作
      print(c);   //输出 31
      c = a - b;  //减法操作
      print(c);   //输出 11
      c = a * b;  //乘法操作
      print(c);   //输出 210
      c = a / b;  //除法操作,两个相除结果为double,即便两个整数相除也为double
      print(c);   //输出 2.1
      c = a % b;  //取余操作
      print(c);   //输出 1
      c = a ~/ b; //取整操作
      print(c);   //输出 2
      print(-c);  //负数操作,输出 -2
    }
    

    Dart 支持自增与自减操作,如下:

    main(){  
      var a, b, c;
      
      a = 21;
      b = 10;
      c = a++ + b;  //a参与运算完毕后自增加1
      print(c);     //输出 31
    
      a = 21;
      b = 10;
      c = ++a + b;   //a自增加1后参与运算
      print(c);      //输出 32
    
      a = 21;
      b = 10;
      c = a-- + b;   //a参与运算完毕后自减1
      print(c);      //输出 31
    
      a = 21;
      b = 10;
      c = --a + b;   //a自减1后参与运算
      print(c);      //输出 20
    }
    

    另外 + 运算符也可用于字符串连接。

    2. 比较运算符

    比较运算符有:==!=><>=<= 。使用例子如下:

    main(){  
      var a = 20;
      var b = 30;
    
      if(a == b) {
        print("a等于b");
      }else if(a != b){
        print("a不等于b");   //输出 a不等于b
      }
    
      if(a > b) {
        print("a大于b");
      }else if(a < b) {
        print("a小于b");    //输出 a小于b
      }
    
      if(a >= b) {
        print("a大于等于b");
      }else if(a <= b) {
        print("a小于等于b");   //输出 a小于等于b
      }
    }
    
    3. 类型运算符

    Dart 中类型运算符有三种:isasis! ,用于运行时检查类型。

    is 运算符用来判断数据是否属于某个类型,属于返回 true ,不属于返回 false 。如果ojb 实现了 T 定义的接口,则 obj is Ttrue
    is! 运算符用来判断数据是否不属于某个类型,不属于返回 true , 属于返回 false
    as 运算符用来做类型转换,此转换并非真正的转换,而是把原对象当做目标对象使用,不会改变原对象。当使用 as 运算符时,应先确定原对象是否属于目标类型,如果不是目标类型的子类或实例不能使用 as 运算符。as 也可用于做指定库的前缀操作(后续会讲到)。

    main(){  
      var str = "this is a string!";
      if(str is String) {
        print("str 是字符串");
      }else{
        print("str 不是字符串");
      }
    
      var a = 10;
    
      if(a is! String) {
        print("a 不是字符串");
      }else{
        print("a 是字符串");
      }
    
      var b =(a as num) + 10;  //如不确定a是否为num的实例或子类,可以使用is操作符做先行判断。如无法转换会抛出异常
      print(b);
    }
    
    4. 逻辑运算符

    逻辑运算符是针对布尔值进行运算的运算符,包括:!||&&

    ! 逻辑非运算符,其只有一个操作数。当操作数布尔值为 true 时,运算结果为 false ,运算数布尔值为 false,运算结果为 true
    || 逻辑或运算符,有两个操作数。当操作数中至少有一个为 true 时,结果为 true ,操作数都为 false ,结果为 false
    && 逻辑与运算符,有两个操作数。当操作数中至少有一个为 false 时,结果为 false ,操作数都为 true ,结果为 true

    ||&& 均为短路运算符。

    main(){  
      print(!true);         //输出 flase
      print(!false);        //输出 true
    
      print(true || false); //输出 true
      print(false || true); //输出 true
      print(true || true);  //输出 true
      print(false || false);//输出 false
    
      print(true && false); //输出 false
      print(false && true); //输出 false
      print(true && true);  //输出 true
      print(false && false);//输出 false
    }
    
    5. 条件运算符

    条件运算符包括:?:????=

    main(){
      var a = 10;
      var b = 20;
      var c = a>b ? a : b;  //如果a大于b则返回a的值赋给c,否则返回b的值赋给c
      print(c);  
    
      //?? 与 ??= 一样,为空运算符
      print(a ?? 100); //输出 10  如果a为null则将100赋值给a,如果a不为null则使用a的值 
    
      var d;
      print(d ??= 200); //输出200
    }
    
    6. 位运算符

    位运算符是针对二进制位进行操作的运算符。包括:&|^~<<>>

    & 按位与运算符,是将两个操作数的每一个二进制位分别做与运算,对应的两个二进制位都为1则结果为1,否则为0。
    | 按位或运算符,是将两个操作数的每一个二进制位分别做或运算,对应的两个二进制位至少有一个为1则结果为1,否则为0。
    ^ 按位异或运算符,是将两个操作数的每一个二进制位分别做异或运算,对应的两个二进制位相同(同为1或同为0)则结果为0,否则为1。
    ~ 按位取反运算符,只有一个操作数,是将操作数的每一个二进制位进行取反操作,即1取反为0,0取反为1。
    << 按位左移运算符,是将操作数的每一个二进制位向左移动指定的位数。每左移一位相当于原数值乘2。
    >> 按位右移运算符,是将操作数的每一个二进制位向右移动指定的位数。每右移一位相当于原数值除以2。

    main(){ 
      int a = 10;  //二进制为00001010
      int b = 5;   //二进制为00000101  
    
      print(a & b);  //运算后二进制为0000 0000,输出结果为 0
      print(a | b);  //运算后二进制为0000 1111,输出结果为 15 
      print(a ^ b);  //运算后二进制为0000 1111,输出结果为 15
      print(~a);     //运算后二进制为1111 0101,输出结果为 -11  可以通过-(a+1)公式快速得出结果。
      print(a << 2); //运算后二进制为0010 1000,输出结果为 40
      print(b >> 2); //运算后二进制为0000 0001,输出结果为 1
    }
    
    7. 复合运算符

    复合运算符是多种简单运算的复合,包括:+=-=*=/=~/=%=<<=>>=&=^=|=

    main(){ 
      double a = 10.0;  //二进制为00001010
      int b = 20;   //二进制为00000101  
    
      print(a += 10);   //输出(此时的a值) 20,0
      print(a -= 10);   //输出(此时的a值) 10,0
      print(a *= 10);   //输出(此时的a值) 100,0
      print(a /= 10);   //输出(此时的a值) 10,0
      print(b ~/= 10);  //输出(此时的b值) 2
      print(b %= 10);   //输出(此时的b值) 2
    
      print(b <<= 2);      //输出(此时的b值) 8
      print(b >>= 2);      //输出(此时的b值) 2
      print(b &= 5);       //输出(此时的b值) 0
      print(b ^= 5);       //输出(此时的b值) 5
      print(b |= 5);       //输出(此时的b值) 5
    }
    
    8. 级联运算符

    级联运算符是 Dart 中比较高级的运算符,用于对同一对象执行一系列操作,使用 .. 表示。使用级联运算符可以减少中间变量的生成,如下:

    main(){ 
      List lst = List()
      ..add(1)
      ..add(2)
      ..addAll([3, 4, 5]);
      print(lst);
    }
    

    级联运算符也可以嵌套使用。

    9. 点运算符

    点运算符用来对对象的属性和方法进行操作。使用点运算符操作对象中不存在的属性或方法时会抛出异常,同样也不能操作 null 对象,如果不确定对象是否为空,则可使用条件访问运算符 ?. 。如果需要操作的对象为空会返回 null,否则正常操作。

    main(){ 
      var lst = [1, 2, 3];
      print(lst.length);  //输出 3
      lst = null;
      // print(lst.length);  //运行此行会抛出异常
      print(lst?.length); //输出 null
    }
    

    二、流程控制

    流程控制语句与其他语言没有什么区别,下面简单的只列出代码,不做过多讲解。需要注意在 Dart 中条件的真假只有 truefalse ,或它能得出 truefalse 的表达式。

    1. if 和 else
    main(){
      int score = 80;
      if(score >= 100) {
        print("满分");
      }else if(score >= 60) {
        print("及格");
      }else{
        print("不及格");
      
    
    2. for 、while 、do while
    main(){
      List arr = [1, 2, 3, 4, 5];
      
      //第一种for
      for(int i = 0; i < arr.length; i++) {
        print(arr[I]);
      } 
      print("-----分割线-----");
    
      //第二种for
      for(var x in arr) {
        print(x);
      }
      print("-----分割线-----");
    
      int i = 0;
      while(i < 5) {
        print(arr[I]);
        I++;
      } 
      print("-----分割线-----");
    
      i = 0;
      do{
        print(arr[I]);
        I++;
      }while(i < 5);
    }
    
    3. break 和 continue

    break 用于跳出与 break 最近的循环,continue 用于跳出本次执行的循环。

    main(){
      List arr = [[1, 2], [3, 4, 5], [7, 8, 9]];
    
      //正常的循环,输出1,2,3,4,5,6,7,8,9
      for(int i = 0; i < arr.length; i++) {
        for(int j = 0; j < arr[i].length; j++) {
          print(arr[i][j]);
        }
      }
    
      //break,当j == 1时跳出里层for循环,所以最终只打印了数组的1,3,7
      for(int i = 0; i < arr.length; i++) {
        for(int j = 0; j < arr[i].length; j++) {
    
          if(j == 1) {
            break;
          }
          print(arr[i][j]);
    
        }
      }
    
      //continue 当j==1时,跳出单次循环,继续下次循环 输出 1,3,5,7,9
      for(int i = 0; i < arr.length; i++) {
        for(int j = 0; j < arr[i].length; j++) {
          if(j == 1) {
            continue;
          }
          print(arr[i][j]);
        }
      }    
    }
    
    4. switch 和 case

    Dart 中 switch 参数可以使用整型、字符串或编译时常量,case 后对象必须全部是同一类的实例。通常,每个非空 case 子句都以 break 结尾。结束非空 case 子句的其他有效方法为 continuethrowreturn

    main(){
      String single = "e";
      switch(single) {
        case "h":
          print("h");
          break;
        case "e":
          print("e");
          break;
        case "l":
          print("l");
          break;
        case "o":
          print("o");
          break;
        default:
          print("error");
          break;
      }  
    }
    

    可以使用 continue 来进行跳转执行,如下:

    main(){
      String single = "e";
      switch(single) {
        case "h":
          print("h");
          break;
        case "e":
          print("e");         //输出 e
          continue jumpOther;
        case "l":
          print("l");
          break;
        jumpOther:
        case "o":
          print("o");         //输出 o
          break;
        default:
          print("error");
          break;
      }  
    }
    

    上述代码在 case "o": 上添加了一个 jumpOther 标签,并在 case "e": 处通过 continue jumpOther 进行了调用,输出e后继续执行o。

    三、异常处理

    异常是一种错误,在程序的运行过程中造成异常的情况有很多,如果不加以识别和控制将引发程序被挂起,造成程序崩溃而结束程序。Dart 中的异常都是未经检查的异常。Dart 中提供了 ExceptionError 类型,以及许多预定义的子类型,也可以自定义异常。Dart 程序可以抛出任何非 null 对象,而非仅限于 ExceptionError

    抛出异常

    main(){
      throw FormatException("这是一个FormatException");
      // print("程序结束");  //此处不会被执行
    }
    
    //抛出的异常 Unhandled exception: FormatException: 这是一个FormatException
    
    main(){
      throw 400;  //抛出自定义的任意非null异常
      // print("程序结束");  //此处不会被执行
    }
    
    //抛出的异常 Unhandled exception: 400
    

    捕获异常

    捕获异常的目的在于组织异常的传播,并进行一定的处理措施。可以将有可能发生异常的代码放在 try 代码块中并使用 catch 捕获。如果需要捕获的异常不止一种,可以使用多个 catch 。基本形式如下:

    main(){
      try{
        throw "抛出一个字符串提示异常";
      }on RangeError catch(e) {  
        // print(e);
      }on String catch(e) {
        print("字符串异常");
      }catch(e, s) {  //e为异常信息,s为异常的栈跟踪信息
        print("其他异常:$e");
        print("栈信息:$s");
      }
    }
    

    上面代码主动抛出一个异常,是一句字符串的提示信息,所以下面将执行 print("字符串异常")on 后接一个异常的具体类型,因为我们抛出的是字符串异常信息,所以会进入 on String catch(e) ,当然可以定义其他具体异常类型。如果捕获的异常并非 on 后接的异常类型,则进入最后的未定义具体类型的异常。catch 方法可以有一个参数参数或两个参数,一个参数时,参数为异常提示信息,两个参数时,第一个参数为异常提示信息,第二个为异常的堆栈信息(StackTrace 对象)。

    main(){
     List arr = [1, 2, 3];
      try{
        print(arr[3]);
      }on int catch(e) {  
        print(e);
      }on String catch(e) {
        print("字符异常");
      }catch(e, s) {  //e为异常信息,s为异常的栈跟踪信息
        print("其他异常:$e");
        print("栈信息:$s");
      }
    }
    

    异常异常类型为 RangeError 类型,所以通过 on 捕获的 intString 类型都不对,进入最后的 catch

    即使捕获到了异常,开发者也可以根据具体情况决定是处理、忽略还是继续抛出异常,如果需要继续抛出,可使用 rethrow 关键字。 rethrow 允许部分处理异常或直接继续抛出异常给其他方法处理。

    main(){
     List arr = [1, 2, 3];
      try{
        try{
          print(arr[3]);
        }catch(e){
          rethrow;
        }
      }on int catch(e) {  
        print(e);
      }on String catch(e) {
        print("1");
      }catch(e, s) {  //e为异常信息,s为异常的栈跟踪信息
        print("其他异常:$e");
        print("栈信息:$s");
      }finally {
        print("善后处理或抛出异常后需要继续执行的代码");
      }
    }
    

    此外有时需要无论是否抛出异常都执行指定的代码,则需要使用到 finally 关键字,如下:

    main(){
     List arr = [1, 2, 3];
      try{
        print(arr[3]);
      }on int catch(e) {  
        print(e);
      }on String catch(e) {
        print("字符异常");
      }
      catch(e, s) {  //e为异常信息,s为异常的栈跟踪信息
        print("其他异常:$e");
        print("栈信息:$s");
      }finally {
        print("善后处理或抛出异常后需要继续执行的代码");
      }
    }
    

    四、断言

    Dart 中使用 assert 来调试程序的执行,使用 assert 如果布尔条件为假,则中断正常执行,并抛出异常。assert 中的条件是任何可以转化为布尔类型的对象,即使函数也可以。

    main(){
      print("执行第一步"); //输出 执行第一步
      assert(1 == 1);    //条件为真,继续执行
      print("执行第二步"); //输出 执行第二步
      assert(1 == 2);    //条件为假,抛出异常
      print("执行第三步"); //不执行此处
    }
    
    //以上会抛出如下异常:
    //执行第一步
    //执行第二步
    //Unhandled exception:
    //Failed assertion: line 5 pos 10: '1 == 2': is not true.
    //#0      _AssertionError._doThrowNew  (dart:core-patch/errors_patch.dart:42:39)
    //#1      _AssertionError._throwNew  (dart:core-patch/errors_patch.dart:38:5)
    //#2      main 
    //Dart/demo1.dart:5
    //#3      _startIsolate.<anonymous closure>  (dart:isolate-patch/isolate_patch.dart:307:19)
    //#4      _RawReceivePortImpl._handleMessage  (dart:isolate-patch/isolate_patch.dart:174:12)
    
    //Exited (255)
    

    可以附加自己的说明在 assert 里,如下:

    main(){
      assert(1 == 2, "这里的条件不成立,1不等2");
      print("不会执行");
    }
    

    assert 可以有两个参数,第一个为任意可以解析为布尔值的表达式,第二个为附加说明信息。

    在生产代码中,assert 将被忽略,并且不会评估断言的参数。

    PS:如果您使用的是 VSCode 来运行 以上断言代码,如果安装有 Code Runner 插件并使用此插件来运行代码,则断言不会执行,需要通过 Debug -> Start Debugging 或 Debug -> Start Without Debugging 来运行代码才会执行断言代码。

    更多内容,请关注公众号持续关注。

    wchatq2.png

    相关文章

      网友评论

        本文标题:[Flutter]flutter基础之Dart语言基础(二)

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