Dart语言(二)内置的数据类型

Dart语言(二)内置的数据类型

Dart内置支持下面这些类型:

  • numbers 数字
  • strings 字符串
  • booleans 布尔
  • lists(也被称之为arrays)list和数组
  • sets set集合
  • maps map集合
  • runes(用于在字符串中表示Unicode字符串)
  • symbols 符号

我们可以直接使用字母量来初始化上面的这些类型。例如 'this is a string'是个字面上的字符串,true是一个字面上的布尔。

由于Dart中每个变量引用的都是一个对象,一个类的实例,通常使用构造函数来初始化变量。一些内置的类型具有自己的构造函数。例如,Map()构造函数类创建map,就 new Map();

Numbers(数值)

Dart支持两种类型的数字:

int:整数值,其取值通常位于-2的53次幂和2的53次幂。

double:64-bit(双精度)浮点数。

int和double都是num的子类。num类型定义了基本的操作符,例如+、-、* 、/ ,还定义了abs()、ceil()、和floor()等函数。位操作符,例如 >> 定义在int类中。如果num或者其子类型不满足你的要求,可以参考dart:math库。

注意:不在-2的53次幂到2的53次幂范围内的整数在Dart中的行为和JavaScript中表现不一样。原因在于Dart具有任意精度的整数,而JavaScript没有。

整数是不带小数点的数字。下面是一些定义整数的方式:

var x = 1;
var hex = 0xDEADBEEF;
var bigInt = 34653465834652437659238476592374958739845729;

如果一个数带小数点,则其为double,下面是定义double的一些方式:

var y = 1.1;
var exponents = 1.43e5;

字符串和数字之间转换的方式:

//String -> int
var one = int.parse('1');
assert(one ==1);

//String -> double
var onePointOne = double.parse('1.1');
assert(onePointOne = 1.1);

//int -> String
String onAsString = 1.toString();
assert(oneAsString = '1');

//double -> String
String pigAsString = 3.14159.toStringAsFixed(2);
assert(pigAsString = '3.14');

整数类型支持传统的位移操作:<<、>>、&和 |。例如:

assert((3 << 1) == 6); //0011 << 1 == 0110
assert((3 >> 1) == 1); // 0011 >> 1 == 0001
assert((3 | 4) == 7); // 0011 | 0100 == 0111

数字为编译时常量。很多算术表达式只要器操作数是常量,则表达式结果也是编译时常量。

const msPerSecond = 1000;
const secondsUntilRetry = 5;
const msUntilRetry = secondsUntilRetry * msPerSecond;

Strings字符串

Dart 字符串是UTF-16编码的字符序列。可以使用单引号或者双引号来创建字符串:

var s1 = 'Single quotes work well for string literals.';
var s2 = "Double quotes work just as well.";
var s3 = 'It\'s easy to escape the string delimiter.';
var s4 = "It's even easier to use the other delimiter.";

可以在字符串中使用表达式,用法是这样的: ${expression} 。如果表达式是一个标识符,可以省略{}。如果表达式的结果是为一个对象,则Dart会调用对象的toString()函数来返回一个字符串。

var s = 'string interpolation';

assert('Dart has $s, which is very handy.' ==
       'Dart has string interpolation, ' +
       'which is very handy.');
assert('That deserves all caps. ' +
       '${s.toUpperCase()} is very handy!' ==
       'That deserves all caps. ' +
       'STRING INTERPOLATION is very handy!');

注意: == 操作符判断两个对象的内容是否一样。如果两个字符串包含一样的字符编码序列,则他们是相等的。

可以使用 + 操作符来把多个字符串链接为一个,也可以把多个 字符串放到一起来实现同样的功能:

var s1 = 'String ' 'concatenation'
         " works even over line breaks.";
assert(s1 == 'String concatenation works even over '
             'line breaks.');

var s2 = 'The + operator '
         + 'works, as well.';
assert(s2 == 'The + operator works, as well.');

使用三个单引号或者双引号也可以创建多行字符串对象:

var s1 = '''
You can create
multi-line strings like this one.
''';

var s2 = """This is also a
multi-line string.""";

通过一个r前缀可以创建一个"原始raw"字符串:

//参考 Runes 来了解如何在字符串 中表达 Unicode 字符。
var s = r"In a raw string, even \n isn't special.";

字符串是编译时常量, 带有字符串插值的字符串定义,若干插值表达式引用的为编译时常量则其结果也是编译时常量。

// These work in a const string.
const aConstNum = 0;
const aConstBool = true;
const aConstString = 'a constant string';

// These do NOT work in a const string.
var aNum = 0;
var aBool = true;
var aString = 'a string';
const aConstList = const [1, 2, 3];

const validConstString = '$aConstNum $aConstBool $aConstString';
// const invalidConstString = '$aNum $aBool $aString $aConstList';

booleans布尔值

为了代表布尔值,Dart 有一个名字为 bool 的类型。 只有两个对象是布尔类型的:truefalse 所创建的对象, 这两个对象也都是编译时常量。

当 Dart 需要一个布尔值的时候,只有 true 对象才被认为是 true。 所有其他的值都是 flase。这点和 JavaScript 不一样, 像 1"aString"、 以及 someObject 等值都被认为是 false。

例如,下面的代码在 JavaScript 和 Dart 中都是合法的代码:

var name = 'Bob';
if (name) {
  // Prints in JavaScript, not in Dart.
  print('You have a name!');
}

如果在 JavaScript 中运行,则会打印出 “You have a name!”,在 JavaScript 中 name 是非 null 对象所以认为是 true。但是在 Dart 的生产模式下 运行,这不会打印任何内容,原因是 name 被转换为 false了,原因在于 name != true。 如果在 Dart 检查模式运行,上面的 代码将会抛出一个异常,表示 name 变量不是一个布尔值。

下面是另外一个在 JavaScript 和 Dart 中表现不一致的示例:

if (1) {
  print('JS prints this line.');
} else {
  print('Dart in production mode prints this line.');
  // However, in checked mode, if (1) throws an
  // exception because 1 is not boolean.
}

注意:上面两个示例只能在Dart上产模式下运行,在检查模式下,会抛出异常 变量不是所期望的布尔类型。

Dart 这样设计布尔值,是为了避免奇怪的行为。很多 JavaScript 代码 都遇到这种问题。 对于你来说,在写代码的时候你不用这些写代码: if (nonbooleanValue),你应该显式的 判断变量是否为布尔值类型。例如:

// Check for an empty string.
var fullName = '';
assert(fullName.isEmpty);

// Check for zero.
var hitPoints = 0;
assert(hitPoints <= 0);

// Check for null.
var unicorn;
assert(unicorn == null);

// Check for NaN.
var iMeantToDoThis = 0 / 0;
assert(iMeantToDoThis.isNaN)

Lists集合

也许 array (或者有序集合)是所有编程语言中最常见的集合类型。 在 Dart 中数组就是 List 对象。所以 通常我们都称之为 lists

Dart list 字面上和 JavaScript 的数组字面上类似。下面是一个 Dart list 的示例:

var list = [1, 2, 3];

Lists 的下标索引从 0 开始,第一个元素的索引是 0,list.length - 1 是最后一个元素的索引。 访问 list 的长度和元素与 JavaScript 中的用法一样:

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

list[1] = 1;
assert(list[1] == 1);

在 list 之前添加 const 关键字,可以 定义一个不变的 list 对象(编译时常量):

var constantList = const [1, 2, 3];
// constantList[1] = 1; // Uncommenting this causes an error.

List类型有许多方便的操作list的方法,可以参阅GenericsCollections

Sets

在Dart中set是个无序的collection。

Version note: Although the Set type has always been a core part of Dart, set literals were introduced in Dart 2.2.

创建set集合示例:

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

Note: Dart infers that halogens has the type Set<String>. If you try to add the wrong type of value to the set, the analyzer or runtime raises an error. For more information, read about type inference.

也就是说 你设定了泛型后,你就只能存放泛型指定的类型数据了,存放其他类型的会报错。

创建一个空的set集合,并指定泛型:

var names = <String>{};
// Set<String> names = {}; // This works, too.
// var names = {}; // Creates a map, not a set.

var names = {} 这种情况为什么是创建了一个map,而不是set集合呢,是因为Dart在进行语法检查时,如果没有指定类型,那么dart就会动态创建类型,由于dart语法中,map类型会优先于set集合出现,所以就会先创建一个Map<dynamic,dynamic>类型对象。

添加元素到set集合中使用add()或者addAll()方法:

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

set集合的长度用.length:

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

创建编译时的set集合,只需在集合前面加上const:

final constantSet = const {
  'fluorine',
  'chlorine',
  'bromine',
  'iodine',
  'astatine',
};
// constantSet.add('helium'); // Uncommenting this causes an error.

更多关于set集合的用法可以查看这里Generics and Sets.

Maps集合

通常情况下,一个map中存放的都是键值对,key和value都可以是任意类型的对象,但是key只能出现一次,value可以重复出现。

创建map示例:

var gifts = {
  // Key:    Value
  'first': 'partridge',
  'second': 'turtledoves',
  'fifth': 'golden rings'
};

var nobleGases = {
  2: 'helium',
  10: 'neon',
  18: 'argon',
};

Note: Dart infers that gifts has the type Map<String, String> and nobleGases has the type Map<int, String>. If you try to add the wrong type of value to either map, the analyzer or runtime raises an error. For more information, read about type inference.

要注意泛型

使用 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';

Note: You might expect to see new Map() instead of just Map(). As of Dart 2, the new keyword is optional. For details, see Using constructors.

在dart2中 new 是可选的,var gifts = new Map() 也可var gifts = map();

添加新的键值对和JavaScript中是一样的:

var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds'; // Add a key-value pair

获取map中的值跟JavaScript是一样的:

var gifts = {'first': 'partridge'};
assert(gifts['first'] == 'partridge');

map中操作的key不存在就会返回null:

var gifts = {'first': 'partridge'};
assert(gifts['fifth'] == null);

用.length获取map中存放的key-value的数量:

var gifts = {'first': 'partridge'};
gifts['fourth'] = 'calling birds';
assert(gifts.length == 2);

创建编译时map:

final constantMap = const {
  2: 'helium',
  10: 'neon',
  18: 'argon',
};

// constantMap[2] = 'Helium'; // Uncommenting this causes an error.

For more information about maps, see Generics and Maps.

Runes

在 Dart 中,runes 代表字符串的 UTF-32 code points。

Unicode 为每一个字符、标点符号、表情符号等都定义了 一个唯一的数值。 由于 Dart 字符串是 UTF-16 code units 字符序列, 所以在字符串中表达 32-bit Unicode 值就需要 新的语法了。

通常使用 \uXXXX 的方式来表示 Unicode code point, 这里的 XXXX 是4个 16 进制的数。 例如,心形符号 (♥) 是 \u2665。 对于非 4 个数值的情况, 把编码值放到大括号中即可。 例如,笑脸 emoji (😆) 是 \u{1f600}

String 类 有一些属性可以提取 rune 信息。 codeUnitAtcodeUnit 属性返回 16-bit code units。 使用 runes 属性来获取字符串的 runes 信息。

下面是示例演示了 runes、 16-bit code units、和 32-bit code points 之间的关系:

main() {
  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));
}
屏幕快照 2019-03-30 18.19.38.png

运行结果如上。

注意: 使用 list 操作 runes 的时候请小心。 根据所操作的语种、字符集等, 这种操作方式可能导致你的字符串出问题。 更多信息参考 Stack Overflow 上的一个问题: 我如何在 Dart 中反转一个字符串?

Symbols符号

一个 Symbol object 代表 Dart 程序中声明的操作符或者标识符。 你也许从来不会用到 Symbol,但是该功能对于通过名字来引用标识符的情况 是非常有价值的,特别是混淆后的代码, 标识符的名字被混淆了,但是 Symbol 的名字不会改变。

使用 Symbol 来获取标识符的 symbol 对象,也就是在标识符 前面添加一个 # 符号:

#radix
#bar

Symbol 定义是编译时常量。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容