【Dart语言解密】想要深入了解Dart语法和类型变量吗?

简介: 【Dart语言解密】想要深入了解Dart语法和类型变量吗?

快来读读这篇文章吧!本文从Dart信息表示的角度出发,详细讲解了Dart的基础语法和类型变量。通过本文的学习,你将会对Dart语言有更深入的认识和理解,更好地掌握Dart的开发技巧和实践应用。快来一起解密Dart语言吧!

1 Dart hello world示例

新建main.dart,声明一个带int参数的函数,并通过字符串内嵌表达式的方式把这个参数打印:

printInteger(int a) {
  print('Hello world, this is $a.');
}
main() {
  var number = 2019;
  printInteger(number);
}

输出:

Hello world, this is 2019.

Dart也要求main作执行入口。

2 Dart的变量与类型

可用var或具体类型声明一个变量:

  • 使用var定义变量时,表示类型交由编译器推定
  • 也可用静态类型去定义变量,更清楚和编译器表达意图,这样编辑器和编译器就能使用这些静态类型,向你提供代码补全或编译警告提示

默认,未初始化的变量值都是null,因此不用担心无法判定一个传递过来的、未定义变量到底是undefined,还是烫烫烫而写一堆判断语句。


Dart是类型安全的语言,并且所有类型都是对象类型,都继承自顶层类型Object,因此一切变量值都是类的实例(即对象),数字、布尔值、函数和null也都是继承自Object的对象。


Dart内置基本类型,如 num、bool、String、List和Map,在不引入其他库时可以使用它们声明变量。

2.1 num、bool与String

作为编程语言中最常用的类型,num、bool、String这三种基本类型被我放到了一起来介绍。

Dart的数值类型num,只有两种子类:即64位int和符合IEEE 754标准的64位double。前者代表整数类型,而后者则是浮点数的抽象。在正常情况下,它们的精度与取值范围就足够满足我们的诉求了。

int x = 1;
int hex = 0xEEADBEEF;
double y = 1.1;
double exponents = 1.13e5;
int roundY = y.round();

除了常见的基本运算符,比如+、-、*、/,以及位运算符外,你还能使用继承自num的 abs()、round()等方法,来实现求绝对值、取整的功能。

打开官方文档或查看源码,这些常见运算符也继承自num:

有其他高级运算方法的需求num无法满足,可试用dart:math库,提供如三角函数、指数、对数、平方根等高级函数。

为表示布尔值,Dart使用了一种名为bool的类型。Dart只有两个对象具有bool类型:true和false,都是编译时常量。


Dart类型安全,不能使用 if(nonbooleanValue) 或 assert(nonbooleanValue) 之类在js可正常工作的代码,而应显式检查值。


如下,检查变量是否为0,在Dart中需要显示地与0做比较:


// 检

// 检查是否为0.
var number = 0;
assert(number == 0);
// assert(number); 错误

Dart的String由UTF-16的字符串组成。 和JavaScript一样,构造字符串字面量时既能使用单引号也能使用双引号,还能在字符串中嵌入变量或表达式:你可以使用 ${express} 把一个表达式的值放进字符串。而如果是一个标识符,你可以省略{}。

内嵌表达式例子。把单词’cat’转成大写放入到变量s1的声明中:

var s = 'cat';
var s1 = 'this is a uppercased string: ${s.toUpperCase()}';

为了获得内嵌对象的字符串,Dart会调用对象的 toString() 方法。而常见字符串的拼接,Dart则通过内置运算符“+”实现。比如,下面这条语句会如你所愿声明一个值为’Hello World!'的字符串:

var s2 = 'Hello' + ' ' + 'World!' ;

为了获得内嵌对象的字符串,Dart会调用对象的 toString() 方法。而常见字符串的拼接,Dart则通过内置运算符“+”实现。比如,下面这条语句会如你所愿声明一个值为’Hello World!'的字符串:

var s2 = 'Hello' + ' ' + 'World!' ;

对于多行字符串的构建,你可以通过三个单引号或三个双引号的方式声明,这与Python是一致的:

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

2.2 List与Map

其他编程语言中常见的数组和字典类型,在Dart中的对应实现是List和Map,统称为集合类型。它们的声明和使用很简单,和JavaScript中的用法类似。

接下来,我们一起看一段代码示例。

  • 在代码示例的前半部分,我们声明并初始化了两个List变量,在第二个变量中添加了一个新的元素后,调用其迭代方法依次打印出其内部元素;
  • 在代码示例的后半部分,我们声明并初始化了两个Map变量,在第二个变量中添加了两个键值对后,同样调用其迭代方法依次打印出其内部元素。
var arr1 = ["Tom", "Andy", "Jack"];
var arr2 = List.of([1,2,3]);
arr2.add(499);
arr2.forEach((v) => print('${v}'));
var map1 = {"name": "Tom", 'sex': 'male'};
var map2 = new Map();
map2['name'] = 'Tom';
map2['sex'] = 'male';
map2.forEach((k,v) => print('${k}: ${v}'));

容器里的元素也需要有类型,比如上述代码中arr2的类型是 List,map2的类型则为 Map<String, String>。Dart会自动根据上下文进行类型推断,所以你后续往容器内添加的元素也必须遵照这一类型。


如果编译器自动推断的类型不符合预期,我们当然可以在声明时显式地把类型标记出来,不仅可以让代码提示更友好一些,更重要的是可以让静态分析器帮忙检查字面量中的错误,解除类型不匹配带来的安全隐患或是Bug。


以上述代码为例,如果往arr2集合中添加一个浮点数 arr2.add(1.1),尽管语义上合法,但编译器会提示类型不匹配,从而导致编译失败。


和Java语言类似,在初始化集合实例对象时,你可以为它的类型添加约束,也可以用于后续判断集合类型。


下面的这段代码,在增加了类型约束后,语义是不是更清晰了?

var arr1 = <String>['Tom', 'Andy', 'Jack'];
var arr2 = new List<int>.of([1,2,3]);
arr2.add(499);
arr2.forEach((v) => print('${v}'));
print(arr2 is List<int>); // true
var map1 = <String, String>{'name': 'Tom','sex': 'male',};
var map2 = new Map<String, String>();
map2['name'] = 'Tom';
map2['sex'] = 'male';
map2.forEach((k,v) => print('${k}: ${v}'));
print(map2 is Map<String, String>); // true

2.3 常量定义

如果你想定义不可变的变量,则需要在定义变量前加上final或const关键字:

  • const,表示变量在编译期间即能确定的值;
  • final则不太一样,,用它定义的变量可以在运行时确定值,而一旦确定后就不可再变。

声明const常量与final常量的典型例子,如下所示:

final name = 'Andy';
const count = 3;
var x = 70;
var y = 30;
final z = x / y;

可以看到,const适用于定义编译常量(字面量固定值)的场景,而final适用于定义运行时常量的场景。

3 总结

通过上面的介绍,相信你已经对Dart的基本语法和类型系统有了一个初步的印象。这些初步的印象,有助于你理解Dart语言设计的基本思路,在已有编程语言经验的基础上快速上手。


而对于流程控制语法:如 if-else、for、 while、 do-while、 break/continue、switch-case、assert,由于与其他编程语言类似,在这里我就不做一一介绍了,更多的Dart语言特性需要你在后续的使用过程中慢慢学习。使用Dart过程, 官方文档 是最重要学习资料。

  • 在Dart中,所有类型都是对象类型,都继承自顶层类型Object,因此一切变量都是对象,数字、布尔值、函数和null也概莫能外;
  • 未初始化变量的值都是null;
  • 为变量指定类型,这样编辑器和编译器都能更好地理解你的意图。

4 FAQ

对于集合类型List和Map,如何让其内部元素支持多种类型(比如,int、double)呢?又如何在遍历集合时,判断究竟是何种类型呢?

在Dart语言中,List和Map支持存储多种类型的元素。可通过泛型指定集合内部元素的类型。如:

List<dynamic> myList = [1, 2.0, 'three'];
Map<String, dynamic> myMap = {'name': 'Alice', 'age': 30, 'height': 1.65};

List和Map的元素类型分别为dynamic,表示可存储任意类型的元素。

如要在遍历集合时判断元素类型,使用Dart中的类型检查运算符is。如:

// 使用is运算符判断了每个元素的类型,并打印了相应信息。
List<dynamic> myList = [1, 2.0, 'three'];
for (var element in myList) {
  if (element is int) {
    print('$element is an integer');
  } else if (element is double) {
    print('$element is a double');
  } else if (element is String) {
    print('$element is a string');
  }
}


目录
相关文章
|
数据采集 JavaScript 前端开发
爬虫与反爬虫
本文介绍了爬虫与反爬虫的基本概念。爬虫是自动抓取互联网信息的程序,通常使用HTTP请求和解析技术获取数据。反爬虫技术包括验证码、User-Agent检测、IP限制、动态加载和数据接口限制等,用于阻止或限制爬虫访问。开发者需了解这些反爬虫策略,并采取相应措施应对。同时,网站运营者在实施反爬虫时也应考虑用户体验。
|
6月前
|
人工智能 自然语言处理 搜索推荐
JeecgBoot AI 应用开发平台,AIGC 功能介绍
JeecgBoot推出AIGC功能模块,包含AI应用开发平台与知识库问答系统,支持AI流程编排、模型管理、知识库训练及向量库对接。基于LLM大语言模型,提供智能对话、RAG检索增强生成等功能,兼容多种大模型(如DeepSeek、Qwen等)。平台结合低代码与AIGC,适用于复杂业务场景,支持快速原型到生产部署,助力用户打造个性化智能体,如“诗词达人”或“翻译助手”,并可嵌入第三方系统提升交互能力。项目开源,欢迎体验与交流。
235 0
JeecgBoot AI 应用开发平台,AIGC 功能介绍
|
机器学习/深度学习 人工智能
8个特征工程技巧提升机器学习预测准确性
8个特征工程技巧提升机器学习预测准确性
8个特征工程技巧提升机器学习预测准确性
|
存储 SQL 关系型数据库
MySQL语句详解:从基础到进阶的全面指南
MySQL语句详解:从基础到进阶的全面指南
|
安全 索引
elasticsearch异常问题
elasticsearch异常问题
419 0
|
SQL 安全 算法
网络安全与信息安全:构建数字世界的防线在数字化浪潮席卷全球的今天,网络安全与信息安全已成为维系社会秩序、保障个人隐私与企业机密的重要基石。本文旨在深入探讨网络安全漏洞的本质、加密技术的前沿进展以及提升安全意识的有效策略,为读者揭示数字时代下信息保护的核心要义。
本文聚焦网络安全与信息安全领域,详细剖析了网络安全漏洞的形成机理、常见类型及其潜在危害,强调了及时检测与修复的重要性。同时,文章系统介绍了对称加密、非对称加密及哈希算法等主流加密技术的原理、应用场景及优缺点,展现了加密技术在保障数据安全中的核心地位。此外,针对社会普遍存在的安全意识薄弱问题,提出了一系列切实可行的提升措施,如定期安全培训、强化密码管理、警惕钓鱼攻击等,旨在引导公众树立全面的网络安全观,共同构筑数字世界的安全防线。
|
Java
Java 抽象类详解
在 Java 中,抽象类是一种特殊类,用于提供基础定义并派生具体子类,支持代码复用。它包含抽象方法(无实现)和具体方法(有实现),不能被实例化,需用 `abstract` 关键字定义。子类必须实现所有抽象方法,除非子类也是抽象类。抽象类可用于定义模板或框架,确保子类实现特定方法。通过示例展示了如何定义抽象类 `Animal` 及其子类 `Dog` 和 `Cat`,并在主类中调用相关方法。使用抽象类可以提高代码复用性和设计质量,但也可能增加维护难度和性能开销。
439 8
|
存储 关系型数据库 数据库
在 Postgres 中使用 Insert Into Select
【8月更文挑战第11天】
840 0
在 Postgres 中使用 Insert Into Select
|
机器学习/深度学习 敏捷开发 人工智能
探索软件测试中的AI辅助技术
【6月更文挑战第12天】在软件开发生命周期中,测试环节是确保产品质量的关键环节。随着人工智能技术的飞速发展,AI辅助的软件测试方法正在改变传统的测试流程。本文将探讨AI如何优化测试过程,提高缺陷检测的准确性和效率,并预测未来AI在软件测试领域的应用趋势。
340 1
|
自然语言处理 语音技术
语言大模型和文本大模型的区别
【2月更文挑战第16天】语言大模型和文本大模型的区别
662 2
语言大模型和文本大模型的区别