美文网首页Dart
Dart - 内置类型(List、Set、Map、Runes)

Dart - 内置类型(List、Set、Map、Runes)

作者: LouisXWB | 来源:发表于2019-12-09 18:25 被阅读0次

    这节继续学习Dart的内置类型,List、Set和Map。

    list

    数组 Array 是几乎所有编程语言中最常见的集合类型,在 Dart 中数组由 List 对象表示。

    Dart 中 List 字面量看起来与 JavaScript 中数组字面量一样。下面是一个 Dart List 的示例:

    var list = [1, 2, 3];
    

    这里 Dart 推断出list 的类型为 List<int>,如果往该数组中添加一个非 int 类型的对象则会报错。

    如果想要创建一个编译时常量的 List,在 List 字面量前添加 const关键字即可:

    var constantList = const [1, 2, 3];
    // 取消注释将导致出错 (Uncommenting this causes an error.)
    // constantList[1] = 1; 
    

    Dart 在 2.3 引入了 扩展操作符(...)和 null-aware 扩展操作符(...?),它们提供了一种将多个元素插入集合的简洁方法。
    例如,你可以使用扩展操作符(...)将一个 List 中的所有元素插入到另一个 List 中:

    var list = [1, 2, 3];
    var list2 = [0, ...list];
    assert(list2.length == 4);
    

    如果扩展操作符右边可能为 null ,你可以使用 null-aware 扩展操作符(...?)来避免产生异常:

    var list;
    var list2 = [0, ...?list];
    assert(list2.length == 1);
    

    Dart 在 2.3 还同时引入了 Collection IfCollection For,在构建集合时,可以使用条件判断(if)和循环(for)。

    下面示例是使用 Collection If 来创建一个 List 的示例,它可能包含 3 个或 4 个元素:

    var nav = [
      'Home',
      'Furniture',
      'Plants',
      if (promoActive) 'Outlet'
    ];
    

    下面示例是使用 Collection For 将列表中的元素修改后添加到另一个列表中的示例:

    var listOfInts = [1, 2, 3];
    var listOfStrings = [
      '#0',
      for (var i in listOfInts) '#$i'
    ];
    assert(listOfStrings[1] == '#1');
    

    Set

    尽管 Set 类型(type) 一直都是 Dart 的一项核心功能,但是 Set 字面量(literals) 却是在 Dart2.2 中才加入的。

    下面是使用 Set 字面量来创建一个 Set 集合的方法:

    var halogens = {'fluorine', 'chlorine', 'bromine', 'iodine', 'astatine'};
    

    可以使用在 {} 前加上类型参数的方式创建一个空的 Set,或者将 {} 赋值给一个 Set 类型的变量:

    var names = <String>{}; // 类型+{}的形式创建Set。
    // 声明类型变量的形式创建 Set (This works, too).
    // Set<String> names = {}; 
    // var names = {}; 
    // 这样的形式将创建一个 Map 而不是 Set (Creates a map, not a set.)
    

    疑问:用{}声明返回的是Set 还是 map?
    ⚠️:" Map 字面量语法同 Set 字面量语法非常相似。因为是先有的 Map 字面量语法,所以 {} 默认是 Map 类型。如果忘记在 {} 上注释类型或赋值到一个未声明类型的变量上,那么 Dart 会创建一个类型为 Map<dynamic, dynamic> 的对象。"

    向一个已存在的 Set 中添加项目可以使用 add() 方法或 addAll() 方法:

    var elements = <String>{};
    elements.add('fluorine');
    elements.addAll(halogens);
    

    使用 .length 可以获取 Set 中元素的数量:

    var elements = <String>{};
    elements.add('fluorine');
    elements.addAll(halogens);
    assert(elements.length == 5);
    

    可以在 Set 字面量前添加 const 关键字创建一个 Set 编译时常量:

    final constantSet = const {
      'fluorine',
      'chlorine',
      'bromine',
      'iodine',
      'astatine',
    };
    // constantSet.add('helium');
     // 取消注释将导致出错 (Uncommenting this causes an error).
    

    从 Dart 2.3 开始,Set 可以像 List 一样支持使用扩展操作符(... 和 ...?)以及 Collection IfCollection For 操作。

    Map

    Dart 中 Map 通过 Map 字面量和 Map 类型来实现,下面是一对使用 Map 字面量创建 Map 的例子:

    var gifts = {
      // 键:    值
      'first': 'partridge',
      'second': 'turtledoves',
      'fifth': 'golden rings'
    };
    
    var nobleGases = {
      2: 'helium',
      10: 'neon',
      18: 'argon',
    };
    

    gifts的类型推断为Map<String, String>,而 nobleGases 的类型推断为 Map<int, String>。如果你向这两个 Map 对象中添加不正确的类型值,将导致运行时异常。

    你也可以使用 Map 的构造器创建 Map:

    var gifts = Map();
    gifts['first'] = 'partridge';
    gifts['second'] = 'turtledoves';
    gifts['fifth'] = 'golden rings';
    
    var nobleGases = Map();
    nobleGases[2] = 'helium';
    nobleGases[10] = 'neon';
    nobleGases[18] = 'argon';
    

    疑问:这里为什么使用 Map() 而不是使用 new Map() 构造 Map 对象?
    ⚠️:因为从Dart2 开始,构造对象的 new 关键字可以被省略掉。

    从 Dart 2.3 Map 也可以像 List 一样支持使用扩展操作符(... 和 ...?)以及 Collection IfCollection For 操作。

    Runes

    Dart 使用 Runes 符文来表示 UTF-32 编码的字符串。

    Unicode 编码为每一个字母、数字和符号都定义了一个唯一的数值。因为 Dart 中的字符串是一个 UTF-16 的字符序列,所以如果想要表示 32 位的 Unicode 数值则需要一种特殊的语法。

    通常使用 \uXXXX 来表示 Unicode 字符,XXXX 是一个四位数的 16 进制数字。例如心形字符(♥)的 Unicode 为 \u2665。对于不是四位数的 16 进制数字,需要使用大括号将其括起来。例如大笑的 emoji 表情(😆)的 Unicode 为 \u{1f600}。

    String 类中有一些属性可以用来提取字符串的 Rune 符文信息。codeUnitAtcodeUnit 属性返回 16 位代码单元。runes 属性可以获取字符串的 Runes 符文。

    下面的例子说明了 Rune、16位代码单元、32位代码单元之间的关系:

      var clapping = '\u{1f44f}';
      print(clapping);
      print(clapping.codeUnits);
      print(clapping.runes.toList());
    
      Runes input = new Runes(
          '\u2665  \u{1f605}  \u{1f60e}  \u{1f47b}  \u{1f596}  \u{1f44d}');
      print(new String.fromCharCodes(input));
    

    Console:

    👏
    [55357, 56399]
    [128079]
    ♥  😅  😎  👻  🖖  👍
    

    ⚠️备忘
    在使用 List 操作 Rune 的时候需要小心,根据所操作的语种、字符集等不同可能会导致字符串出现问题,具体可参考 Stack Overflow 中的提问: 我如何在 Dart 中反转一个字符串?

    相关文章

      网友评论

        本文标题:Dart - 内置类型(List、Set、Map、Runes)

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