<基础>Dart语法一

作者: 玉圣 | 来源:发表于2019-04-01 00:25 被阅读3次

    说明:
    此篇不对Dart语法进行详细总结(在有编程语言的基础,即学习过其他面向对象语言之上),而对比Java进行一些语法的异同进行总结。

    内容:

    • 关键字
    • 数据类型
    • 操作符
    • 控制语句
    • 方法
    • 面向对象
    • 枚举与泛型
    • 库和可见性
    • 异步支持
    • 元数据

    参考资料:
    Dart学习笔记
    Flutter与Dart 入门
    Dart语法学习

    一、关键字

    关键字
    abstract [1] do import [1] super
    as [1] var continue dynamic [1]
    assert [2] else interface sync *[2]
    enum is implements [1] export [1]
    async *[2] this library [1] throw
    await new covariant true
    break null external [1] factory [1]
    case try extends typedef [1]
    catch false operator [1] switch
    class final finally void
    const part [1] rethrow while
    in for return with
    mixin get [1] set [1] yield *[2]
    default if static [1] deferred [1]

    带有[1] 的关键字是 内置关键字。避免把内置关键字当做标识符使用。 也不要把内置关键字 用作类名字和类型名字。 有些内置关键字是为了方便把 JavaScript 代码移植到 Dart 而存在的。 例如,如果 JavaScript 代码中有个变量的名字为 factory, 在移植到 Dart 中的时候,你不必重新命名这个变量。

    带有[2] 的关键字,是在 Dart 1.0 发布以后又新加的,用于 支持异步相关的特性。 你不能在标记为 async*、或者 sync* 的方法体内 使用 asyncawait、或者 yield 作为标识符。 详情请参考:异步支持

    所以其他单词都是 保留词。 你不能用保留词作为关键字。

    二、数据类型

    1、变量与常量

    • 变量声明与初始化:
      1.使用var 声明变量,此时没有明确类型,编译的时候根据值明确类型
      2.明确变量类型,来帮助 Dart 去捕获异常以及 让代码运行的更高效
      3.未初始化时,变量默认值为null
      4.如果对象不限于单一类型(没有明确的类型),请使用Object或dynamic关键字
        var name = ‘Bob’; 
        Object name1 = '张三';
         //动态类型
        dynamic name2 = '李四';
        // 显示声明将被推断类型, 可以使用String显示声明字符串类型
        String name3 = 'Bob' ;
      
    • final and const
      1.被finalconst 修饰的变量只能赋值一次,不可更改变量值
      2.一个 final 变量只能被初始化一次; const变量是一个编译时常量,(Const变量是隐式的final),如果 const 变量在类中,请定义为 static const。
      3.被final或者const修饰的变量,变量类型可以省略,建议指定数据类型。
      4.被final修饰的顶级变量或类变量在第一次声明的时候就需要初始化,否则会提示错误:
      // The final variable 'outSideFinalName' must be initialized.
      final String outSideFinalName
      
      5.const关键字不只是声明常数变量,您也可以使用它来创建常量值,以及声明创建常量值的构造函数,任何变量都可以有一个常量值。
       // 注意: [] 创建的是一个空的list集合
       // const []创建一个空的、不可变的列表(EIL)。
       var varList = const []; // varList 当前是一个EIL
       final finalList = const []; // finalList一直是EIL
       const constList = const []; // constList 是一个编译时常量的EIL
      
       // 可以更改非final,非const变量的值
       // 即使它曾经具有const值
       varList = ["haha"];
      
       // 不能更改final变量或const变量的值
       // 这样写,编译器提示:a final variable, can only be set once
       // finalList = ["haha"];
       // 这样写,编译器提示:Constant variables can't be assigned a value  
       // constList = ["haha"];
      
      注意:实例变量可以为 final 但是不能是 const 。

    2、数据类型(内置类型)

    • num(数值)
      1、int:其取值通常位于 -253 和 253 之间
      2、double:64-bit (双精度) 浮点数,符合 IEEE 754 标准。
      3、数值型操作:

      • 运算符:+-*/~/%
        其中~/为整除
      • 常用属性:isNaN (是否非数字),isEven(是否为偶数),isOdd(是否为奇数)
      • 常用方法:abs()round()floor()ceil()toInt()toDouble()
       int a = 1;
       print(a);
       
       double b = 1.12;
       print(b);
       
       // String -> int
       int one = int.parse('1');
       // 输出3
       print(one + 2);
       
       // String -> double
       var onePointOne = double.parse('1.1');
       // 输出3.1
       print(onePointOne + 2);
      
       // int -> String
       String oneAsString = 1.toString();
       // The argument type 'int' can't be assigned to the parameter type 'String'
       //print(oneAsString + 2);
       // 输出 1 + 2
       print('$oneAsString + 2');
       // 输出 1 2
       print('$oneAsString 2');
      
       // double -> String 注意括号中要有小数点位数,否则报错
       String piAsString = 3.14159.toStringAsFixed(2);
       // 截取两位小数, 输出3.14
       print(piAsString);
       
       String aString = 1.12618.toStringAsFixed(2);
       // 检查是否四舍五入,输出1.13,发现会做四舍五入
       print(aString);
      
    • String(字符串)
      1、String的创建:

      • 使用单引号'',双引号""
      • 使用三个 引号'''或双引号""" 创建多行字符串
      • 使用r 创建原始 raw 字符串
        var s1 = '单引号字符串';
        var s2 = "双引号字符串";
        var s3 = '''
                   单引号多创建的多行的字符串,
                   第二行
              ''';
        var s4 = """
                   双引号多创建的多行的字符串,
                   第二行
              """;
        //使用r创建原始’raw‘字符串,\n不换行
        var s5 = r"使用r创建原始’raw‘字符串,\n不换行";
        

      2、字符串操作:

      • 运算符:+*==[]

         String a = "hello";
         String b = a + " Dart!";
         //hello Dart!
         print(b);
         
         String c = b*2;
         //hello Dart!hello Dart!
         print(c);
         
         String d = "hello Dart!";
         //true
         print(d==b);
         
         String e = d[0];
         //h
         print(e);
        
      • 插值表达式:${expression}

        int e1 = 1;
        int e2 = 2;
        //a = 1
        print("a = $a");
        //e1 + e2 = 3
        print("e1 + e2 = ${e1 + e2}");
        
      • 常用属性:length(长度),isEmpty(是否为空),isNotEmpty(是否非空)

      • 常用方法:contains()subString()startsWith()endsWith()indexOf()lastIndexOf()toLowerCase()toUpperCase()trim()trimLeft()trimRight()split()replaceXxx()

      • 更多API详见官网:String class

      3、StringBuffer

      • 使用 StringBuffer 创建字符串,当调用其 toString() 函数时,才会创建一个 新的 String 对象。
      • write() :将参数字符串加入StringBuffer 对象中
      • writeAll() :此函数有一个可选的参数来指定每个字符串的分割符
        var sb = new StringBuffer();
        //这里用到了级联操作符
        sb..write('Use a StringBuffer for ')
          ..writeAll(['efficient', 'string', 'creation'], ' ')
          ..write('.');
        
        var fullString = sb.toString();
        //Use a StringBuffer for efficient string creation.
        printI(fullString);
        
    • bool(布尔型)
      1、使用bool表示布尔型
      2、布尔值只有个truefalse,它们都是编译时常量。
      3、Dart的类型安全意味着您不能使用 if(nonbooleanValue) 或 assert(nonbooleanValue) 等代码, 相反Dart使用的是显式的检查值。

    • List(数组、列表)
      1、List的创建:

      • 创建List:
        var lvs = [1, 2, 3];
        
      • 创建不可变的List:
        //其中的值不能修改
        var lcs = const [1, 2, 3];
        //报错:unsupported operation: Cannot modify for an unmodifiable list
        lcs[0] = 5;
        
      • 构造创建:
        var lns = new List();
        

      2、常用操作:

      • [] 取值,length 数组长度

      • 方法:
        add() 添加元素,insert() 在指定位置插入,
        remove() 移除元素,clear() 清空数组,
        indexOf() 获取指定元素位置,lastIndexOf() 倒序获取指定元素位置,
        sort() 排序,sublist() 截取数组,shuffle()
        asMap() 转换为Map,forEach() 循环遍历,
        更多API详见官网:List<E> class

         //创建一个int类型的list
         List list = [10, 7, 23];
         // 输出[10, 7, 23]
         print(list);
         
         // 使用List的构造函数,也可以添加int参数,表示List固定长度,不能进行添加 删除操作
         var fruits = new List();
         
         // 添加元素
         fruits.add('apples');
         
         // 添加多个元素
         fruits.addAll(['oranges', 'bananas']);
         
         List subFruits = ['apples', 'oranges', 'banans'];
         // 添加多个元素
         fruits.addAll(subFruits);
         
         // 输出: [apples, oranges, bananas, apples, oranges, banans]
         print(fruits);
         
         // 获取List的长度
         print(fruits.length);
         
         // 获取第一个元素
         print(fruits.first);
         
         // 获取元素最后一个元素
         print(fruits.last);
         
         // 利用索引获取元素
         print(fruits[0]);
         
         // 查找某个元素的索引号
         print(fruits.indexOf('apples'));
         
         // 删除指定位置的元素,返回删除的元素
         print(fruits.removeAt(0));
        
         // 删除指定元素,成功返回true,失败返回false
         // 如果集合里面有多个“apples”, 只会删除集合中第一个改元素
         fruits.remove('apples');
        
         // 删除最后一个元素,返回删除的元素
         fruits.removeLast();
        
         // 删除指定范围(索引)元素,含头不含尾
         fruits.removeRange(start,end);
        
         // 删除指定条件的元素(这里是元素长度大于6)
         fruits.removeWhere((item) => item.length >6);
        
         // 删除所有的元素
         fruits.clear();
        
      • 说明:List 是泛型类型,所以可以指定里面所保存的数据类型

           // This list should contain only strings.
           var fruits = new List<String>();
              
           fruits.add('apples');
           var fruit = fruits[0];
           assert(fruit is String);
           
           // Generates static analysis warning, num is not a string.
           fruits.add(5);  // BAD: Throws exception in checked mode.
        
    • Set(无序集合)
      1、Dart 中的 Set 是一个无序集合,里面不能保护重复的数据。 由于是无序的,所以无法通过索引来从 set 中获取数据。
      2、相关方法:
      add() 添加一个元素, addAll() 添加一个数组
      contains() 是否包含一个元素,containsAll() 是否包含多个元素
      intersection() 获取两个集合的交集
      更多API详见官网:Set<E> class

         void main() {
           var sts = new Set();
           sts.add("1");
           sts.addAll(['gold', 'titanium', 'xenon']);
           sts.add("1");  //重复添加相同元素被覆盖
         
           //{1, gold, titanium, xenon}
           print(sts);
         
           //titanium
           print("" + sts.elementAt(2));
           
           //sts==>{1, gold, titanium, xenon}
           print("sts==>$sts");
      
           var sts2 = new Set.from(['xenon', 'argon']);
           //sts2==>{xenon, argon}
           print("sts2==>$sts2");
      
           var sts3 = sts.intersection(sts2);
           //sts3==>{xenon}
           print("sts3==>$sts3");
         }
      

    注: List<E>Set<E>都继承自EfficientLengthIterable<T> ,并最终继承Iterable<E>类。

    • Map(集合)
      1、说明:
      · map 通常也被称之为 字典或者 hash ,也是一个无序的集合,里面 包含一个 key-value 对。map 把 key 和 value 关联起来可以 方便获取数据。和 JavaScript 不同的是, Dart objects 不是 maps。
      · 键和值都可以是任何类型的对象。
      · 每个 键 只出现一次, 而一个值则可以出现多次。
      2、创建:

           //方式一:
           var map1 = {
             "one" : [1, "strValue", true],
             "two" : "twoValue",
           };
           //创建不可变Map
           var mapConst = const {
             "one" : [1, "strValue", true],
             "two" : "twoValue",
           };
      
           //方式二:未指定泛型类型
           var map2 = new Map();
      
           //方式二:指定泛型类型
           var map3 = new Map<int, String>();
      

      3、常用属性/方法:
      length Map长度, keys 返回所有key值,values 返回所有的value值
      isEmpty() 是否为空Map, isNotEmpty() 是否为非空Map
      [] 新增一个元素,remove() 移除一个元素,并将元素返回
      containsKey() 是否包含一个key
      putIfAbsent(key, function) 设置 key 的值,但是只有该 key 在 map 中不存在的时候才设置这个值,否则 key 的值保持不变。该函数需要 一个方法返回 value
      forEach() 遍历Map

           var map1 = {
             "one" : [1, "strValue", true],
             "two" : "twoValue",
           };
           
           //null
           print(map1["x"]);
           //[1, strValue, true]
           print(map1["one"]);
      
           //true
           print(map1.containsKey("one"));
      
           var result = map1.remove("two");
           //result==>twoValue,,map1==>{one: [1, strValue, true]}
           print("result==>$result,,map1==>$map1");
      
           //提示:the argument type 'int' can't be assigned to be parameter type 'String'
           //map1[1] = 123;
      
           var map11 = {
               "one" : [1, "strValue", true],
               "two" : "twoValue",
               2 : new List()
             };
           //不会提示错误
           map11[1] = 123;
      
           //新增一个元素
           map1["three"] = "addValue";
      
           var keys = map1.keys;
           //keys==>(one, three)
           print("keys==>$keys");
           var values = map1.values;
           //values==>([1, strValue, true], addValue)
           print("values==>$values");
      
           map1.putIfAbsent("four", ()=> 1+2);
           map1.putIfAbsent("four", ()=> "返回一个value");
           //map1==>{one: [1, strValue, true], three: addValue, four: 3}
           print("map1==>$map1");
           print("==========================");
      
           /*
           one==>[1, strValue, true]
           three==>addValue
           four==>3
           */
           map1.forEach((key, value)=> {
             print("$key==>$value")
           });
      
           print("==========================");
           /*
           one==[1, strValue, true]
           three==addValue
           four==3
            */
           for(var me in map1.entries) {
             print("${me.key}==${me.value}");
           }
      

      说明:
      1、从上面的代码可以看出,在map中,如果初始的key值都是同一类型,则在通过[] 方式添加的时候,只能添加相同类型的值作为key。
      2、虽然 Map 没有实现 Iterable,但是 Map 的 keys 和 values 属性实现了 Iterable。

        Iterable<K> get keys;
        Iterable<V> get values;
      

      3、和Java一样,在Map中也有一个内部类MapEntry<K, V>,可以通过其属性entries获取到MapEntry<K, V> 类型的迭代器Iterable,以此来进行遍历。

    • dynamic(动态类型)
      1、注意:
      dynamic并非Dart中的内置类型,
      没有指定类型的变量的类型为 dynamic
      dynamic 一般在使用泛型时使用
      2、示例:

      dynamic a = 10;
      //a==>10
      print("a==>$a");
      a = "六六六";
      //a==>六六六
      print("a==>$a");
      
      var ls = new List<dynamic>();
      ls.add("哈哈");
      ls.add(333);
      //ls==>[哈哈, 333]
      print("ls==>$ls");
      

    三、操作符

    1、算数运算符:
    • + 加、- 减、* 乘、/ 除、~/ 取整、% 取模(余)、-expr 负数
    • ++expr 先递增、expr++ 后递增、--expr 先递减、expr--后递减
    2、关系运算符:
    • ==相等、!= 不等、>=大于等于、>大于、<=小于等于、< 小于
    3、逻辑运算符:
    • ! 取反、&& 并且、|| 或者
    4、赋值运算符:
    • =等于、+= 加等于、-= 减等于、
      *= 乘等于、/= 除等于、
      %= 取模(余)等于、~/= 取整等于
      <<= 左移等于、>>= 右移等于
      ^= 非等于、&=且等于、|=或等于
      ??= 判空等于:如果??=左边的变量为无值,则将右边的值赋值给变量,否则不赋值
      int a = 10;
      int b;
      a ??= 20;
      b ??=5;
      //a = 10      a有值10,所以不会赋值20
      print("a = $a");
      //b = 5        b无值,则将5赋值给b
      print("b = $b");
      
    5、位和移位操作符

    & 且、| 或、^ 非、<< 左移、>> 右移

    5、条件表达式

    condition ? expr1 : expr2 三目运算符
    expr1 ?? expr2 返回其中不为空的表达式执行结果

    String a = "Hello";
    String b = "";
    String c = "Dart";
    String d = a ?? b;
    String e = b ?? c;
    //d = Hello
    print("d = $d");
    //e = Dart
    print("e = $e");
    
    6、类型判定操作符

    asis、和 is! 操作符是在运行时判定对象
    as:类型转换
    is:如果对象是指定的类型返回 True
    is!:如果对象是指定的类型返回 False
    具体例子参考面向对象的总结

    7、其他操作符
    • ():使用方法。代表调用一个方法
    • []:访问 List。访问 list 中特定位置的元素
      .:访问 Member(成员)。访问元素,例如 foo.bar 代表访问 foo 的 bar 成员
      ?.:条件成员访问。和 . 类似,但是左边的操作对象不能为 null,例如 foo?.bar 如果 foonull 则返回 null,否则返回 bar 成员
    8、级联操作符

    ..:级联操作符 (..) 可以在同一个对象上 连续调用多个函数以及访问成员变量。使用级联操作符可以避免创建临时变量,并且写出来的代码看起来更加流畅。(具体详见面向对象中的例子)

    querySelector('#button') // Get an object.
      ..text = 'Confirm'   // Use its members.
      ..classes.add('important')
      ..onClick.listen((e) => window.alert('Confirmed!'));
    

    说明:
    第一个方法 querySelector() 返回了一个 selector 对象。后面的级联操作符都是调用这个对象的成员,并忽略每个操作所返回的值。

    四、控制语句

    • if...else,if...else if,if...else if...else
    • for,for...in
      var list = [1, 2, 3, 4, 5];
      for (var item in list) {
         print(item);
      }
      
    • while do-while
    • break continue
    • switch...case
      其中可以使用跳转标签(自定义标签名称)
      Stirng lang = “Dart";
      switch (lang) {
        D:
        case "Dart":
             print("This is Dart!");
             break;
        case "Java":
             print("This is Java!");
             break;
        case "Flutter":
             print("This is Flutter!");
             continue D;
             //break;  //不需要了
        default:
             print("This is NONE!");
             break;
      }
      
      打印结果为:
      This is Flutter!
      This is Dart!
      
    • assert(仅在checked模式有效)

    相关文章

      网友评论

        本文标题:<基础>Dart语法一

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