Dart -- 较Java新特性(一)

作者:opLW
目的:在阅读Dart概览后进行的总结,主要记录Dart相比Java的新特性,包括许多亲自实验后的总结。如有错误还望指正😄
其他文章:
Dart – 较Java新特性(二)
Dart – 较Java新特性(三)

目录

1.变量
2.常量
3.内建类型
4.集合
5.运算符

1.变量
  • 1.1 变量类型 Dart中没有基本数据类型的说法,任何变量都是类的实例并且这些类都继承自Object
  • 1.2 变量的默认值 Dart中所有变量默认值都为null,不像Java中基本类型有其对应的默认值。
  • 1.3 变量的声明
    • var Dart中除了可以像Java一样明确声明变量类型外,还引入var标识符来声明变量,被var修饰的变量的类型由系统根据变量实际值进行推断。
      String name = 'Bob';
      var name = 'Bob'; 
      
    • dynamic dynamic标识符修饰变量时,相当于告诉编译器开发者自己能保证代码正确,不用编译器对这个变量的进行检查。如下代码在编译时不会出现警告,而运行时会抛出异常,因为A类没有foo这个方法。
       void main() {
         dynamic a = A();
         a.foo();
       }
       class A {}
      
      使用dynamic标识符时,开发者需要自行保证正确。
      注意 Dart中的集合类,如果不特别声明泛型的类型,那么默认使用dynamic代替。
  • 1.4 变量的实例化
    • new关键字 在实例化对象时,new关键字变为可选,即可以省略new关键字

2.常量
  • 2.1 final 与Java一样,final修饰的变量代表其只能被设置一次。因为Dart中没有基本变量,所以可以认为被final修饰的变量,其不能引用其他对象。
    • 由于Dart能进行类型推断,所以可以声明变量时可以省略类型。
      final String nickname = 'Bobby';
      final name = 'Bob'; // Without a type annotation
      name = 'Alice'; // Error: 一个 final 变量只能被设置一次。
      
  • 2.2 编译期常量:const
    • const相对于final的要求更高,除了被修饰变量不能引用其他对象外,const修饰的变量为编译期常量,即在编译器编译代码时就确定变量的值。
    • 如果const修饰的常量属于类级别的,那么应该用static const修饰,类似于Javapublic static final修饰的变量。
      void main() {
        print(A.str);
        
        const str1 = 'I am a Char too';
        print(str1);
      }
      class A {
        static const str = 'I am a Char';
      }
      
    • 在字符串中含有算术表达式或变量时,只要变量是编译时常量, 那么算术表达式的结果也是编译时常量;
      void main() {
        print(A.number2);
      }     
      class A {
        static const c = 1;
        static const d = 2;
        static const number2 = 'I am ${c + d}';
      }
      
    • const除了用于声明编译期常量外,也可用于创建编译期常量,这需要该类拥有常量构造函数
      const a = [1,2,3]; // const用于声明变量
      //a = [2,3,4];  再次对a赋值。发生错误,因为a是一个const类型的变量
      
      var b = const [3, 4, 5]; // 创建编译器常量
      //b[0] = 10;  发生错误,因为此时的b指向一个常量,不能对其内容进行修改
      b = [4, 5, 6]; // 正常,因为b是一个var类型变量
      b[0] = 10; //正常,因为此时b已经指向另一个不为const的变量了
      
      var a = const[1,2,3];
      var b = const[1,2,3];
      if (identical(a,b)) {
         print(true);
      }
      // 输出true,因为a和b都指向同一个编译期常量
      

3.内建类型 (Dart自带的类型)
  • 3.1 数字类型 Dart中没有float类型,只有doubleint
    • int取值范围在Dart VM上为 -263 到263-1
    • 只要值中含有小数点那么就认为是double类型
    • 从Dart 2.1开始,必要的时候int字面量会自动转换成 double 类型。
      double z = 1; // 相当于 double z = 1.0.
      
  • 3.2 字符串
    • Dart中字符串可用单引号或者双引号进行声明。
      String str = 'The code can\'t be set'
      String str = "The code can't be set"
      
      1. 如果在用单引号包括的字符串中使用单引号,则需要进行转义。
      2. 如果在用双引号包括的字符串中使用双引号,同样需要进行转义。
      3. 但双引号包括的字符串中使用单引号则不需要转义。
    • 使用连续三个单引号或者三个双引号实现多行字符串对象的创建。
      var s1 = '''
      You can create
      multi-line strings like this one.
      ''';
      
      var s2 = """This is also a
      multi-line string.""";
      
    • 字符串模板 字符串可以通过 ${expression} 的方式内嵌表达式。 如果表达式是一个标识符,则 {} 可以省略。
      String str1 = "I am ${a + b}" 
      String str2 = "I am $a" 
      
    • 原始字符串 通过在字符串前面添加“r”字符,让字符串保持原生输出,即字符串内容是什么就输出什么。
      void main() {
        int a = 1;
        int b = 2;
        final str1 = r"I am ${a + b} can\'t be 3";
        print(str1);
        // 输出:I am ${a + b} can\'t be 3
        
        final str2 = r'I am ${a + b} can\'t be 3';
        print(str2);
        // 错误,详细原因见下方
      }
      
      注意:当原生字符串中含有单引号时,需要使用双引号包裹。否则由于转义字符被忽略,将导致\'中的单引号被误认为是字符串结束,引发错误。
  • 布尔值 Dart中使用bool声明布尔值,有truefalse两个值并且这两个值都为编译期常量。

4.集合
  • 4.1 List
    var list = [1, 2, 3]; // 通过方括号创建
    var length = list.length; // 获取list对象的length属性
    list[1] = 2; // 通过list[i]访问或设置元素
    
  • 4.2 Map
    // 通过键值对和中括号的形式创建Map
    var gifts = {
     // Key: Value
     'first': 'partridge',
     'second': 'turtledoves',
     'fifth': 'golden rings'
    }; // 系统自动推断为Map<String,String>类型
    
    var nobleGases = {
     2: 'helium',
     10: 'neon',
     18: 'argon',
    }; // 系统自动推断为Map<int,String>类型
    
    var gifts = Map(); // 通过实例化Map类创建
    gifts['first'] = 'partridge'; // 通过map[key]访问或设置元素
    
  • 4.3 Set
    // Set是在Map的基础上进行扩展的,所以需要使用“<Type>”特别声明类型
    var names = <String>{}; // 形式一
    Set<String> names = {}; // 形式二
    
    // 不特别声明类型则默认为Map类
    var names = {}; // 这样会创建一个 Map ,而不是 Set 。
    
  • 4.4 Rune
    • 作用 Dart中String类使用UTF-16进行编码,但这种字符集能够表示的字符数量有限,所以Dart中使用Rune类来表示更多字符如emoji表情等。
    • 编码: 全世界存在各种各样的符号如‘a’、'我’及emoji表情,所以为了让计算机识别种类繁多的字符,需要用独一无二的二进制串标记这个字符。
    • 字符集: 编码的字符越多需要的位数越多,但是部分应用可能仅在某个国家使用,不需要使用到他国的字符,所以不需要对其他国家的字符进行编码。因此为了节省资源就出现了字符集。字符集仅对部分字符进行编码,不同的地区使用不同的字符集。
    • Rune 用来表示字符串中的 UTF-32 编码字符,使用如\uXXXX的形式,其中的XXXX代表4个16进制。如果还不够表示则用\u{大于4个X}共6位。
      Runes input = new Runes(
       '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
       // 输出结果是:♥  😅  😎  👻  🖖  👍
      

5.运算符
  • 5.1 算术运算符 Dart中大部分运算符与Java类似,不同的是
    • / 在Dart中/求出的结果是double类型。
    • ~/ 在Dart中~/求出的结果int类型,对应Java中的/运算符。
  • 5.2 关系运算符
    • 判断两个变量是否指向同一对象 Java中使用==符号;Dart使用identical(Object a, Object b)方法,该方法属于dart:core包。
    • == Dart中使用==符号比较两个变量的是否相等,要想使用这个符号,需要在类中重写==运算符。
  • 5.3 类型运算符
    • is 判断一个变量是否属于一个类。如果变量为null或不属于该类则为false,否则返回true并在该作用域内将该变量智能的转化为该类的实例如:
      if (emp is Person) {
        // emp已经默认转为Person类的实例
        emp.firstName = 'Bob';
      }
      
    • !is 判断一个变量是否不属于一个类,不属于则为true
    • as 将一个变量强行转为该类,如果变量为null或不属于该类型则抛出异常
      (emp as Person).firstName = 'Bob';
      
  • 5.4 赋值运算符
    • ??= Dart中除了常规的=赋值运算符外,还有??=运算符,该运算符只有在左边变量为null时,才会将右边的值赋给左边变量。
    • 复合赋值运算符 如Java中的+=赋值运算符在Dart中同样适用
  • 5.5 逻辑运算符&&||等基本与Java中一样
  • 5.6 按位和位移运算符&(与运算符)|(或运算符)等基本与Java中一样
  • 5.7 条件表达式 Dart中除了有三目条件表达式exper ? trueExper : falseExper外,还有
    • exper1 ?? exper2 exper1不为null则执行并返回exper1exper1null则执行并返回exper2
  • 5.8 级联运算符 Dart中的级联运算符有点类似Kotlin中的作用域函数
    • 可以对同一个对像进行一系列的操作如调用函数、 访问对象的字段属性,每句代码执行后的返回值会被忽略。
      querySelector('#confirm') // 获取对象。
        ..text = 'Confirm' // 调用成员变量。
        ..classes.add('important')
        ..onClick.listen((e) => window.alert('Confirmed!'));
      
    • 级联的代码可以嵌套
      final addressBook = (AddressBookBuilder()
      ..name = 'jenny'
      ..email = 'jenny@example.com'
      ..phone = (PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
       .build();
      
    • 切记级联的符号是两个点不是一个点。错误示范如下:
      var sb = StringBuffer();
      sb.write('foo') // 少写了一个点,导致错误
        ..write('bar'); // Error: 'void' 没有定义 'write' 函数。
      
  • 5.9 其他运算符
    • ?. Dart与Kotlin类似有一个空安全访问符号。如例子foo?.bar,如果foo不为null才会访问bar属性,如果为null则不访问,以此来避免NPE。

万水千山总是情,麻烦手下别留情。
如若讲得有不妥,文末留言告知我,
如若觉得还可以,收藏点赞要一起。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值