文章

Dart 编程语言概览

Dart基础概念和内部原理

Dart汇总请点击这里

@[toc]

前言

该不该学习Dart语言?

如果你在2018年问这个问题,收到答案肯定是不应该学,因为2018年Dart被评为了最不应该学习语言的榜首。

如果您在2019年,我建议学习Dart,因为Dart被评为2019年开发者最希望学习的榜首。

2018 和2019为何出现如此截然相反的态度呢,原因很简单其亲爹谷歌已经将其册封为太子,而且还为其娶了一个叫Flutter的太子妃,未来新一代操作系统fuchsia将以Dart为主力语言。而且谷歌最赚钱的Adwords广告业务已经采用Dart进行开发。站在巨人肩膀上的Dart肯定能够成为未来的主流语言。

Dart发展史

  • Dart语言的诞生

    2011年10月10日,Google 在 GOTO 开发者大会上首次发布了 Dart 编程语言。Dart 的设计目标是为现代 Web 应用程序提供高效的编程语言,作为 JavaScript 的替代品。

    Dart的设计目标: - 创建用于Web编程的结构化但灵活的语言 - 使Dart 对程序员感到熟悉和自然,从而易于学习。 - 确保Dart 在从小型手持设备到服务器端执行的所有现代Web浏览器和环境中提供高性能。

  • 第一个正式稳定的版本

    2013年11月14日,Dart 1.0 正式发布,标志着语言进入生产环境。 Dart 1.0 提供了稳定的 SDK,支持 Dart-to-JavaScript 编译,并带来了 Dartium(内置 Dart VM 的 Chromium 浏览器)。从13至18年,Dart不温不火,特别是其运行效率成为了被人诟病的槽点。

  • Flutter 框架的引入

    2015年:Google 宣布 Flutter 项目,作为使用 Dart 语言的跨平台 UI 框架。Flutter 的引入极大地推动了 Dart 的普及,特别是在移动开发领域。

  • Dart 2.0 重生的版本

    Dart 2.0 专注于为开发现代应用程序提供更高效的开发体验,特别是与 Flutter 的集成。2018年8月8日,Dart 2.0 版本发布,对Dart进行全新改版,带来了显著的改进,从底层重构了Dart,加入了很多面向未来的新特性,包括强类型系统和改进的开发工具,语言性能大幅提高。还重写了Dart web platform提供了一套高性能、可扩展的生产工具。

    Dart2标志着Dart作为主流编程语言的重生,为移动和Web应用程序实现快速开发并拥有出色的用户体验。(使开发客户端应用程序的开发人员能够使用减少重复样板的语言,框架和组件来提高工作效率,并让他们专注于业务逻辑) Dart 2专注于三个领域:语言功能不断加强并更加严谨;支持web和移动客户端开发;丰富工具箱和组件;

  • Dart 2.12 Null Safety

    2021年3月3日Dart 2.12 发布,引入了 Null Safety(空安全)功能。这是 Dart 语言的一个重要里程碑,提供了静态类型检查,防止空引用异常,从而提高代码的可靠性和安全性。

    这也是接入Flutter之后第一次大规模更新,工程项目中所有的依赖项,工程自身,以及编码细节均进行更新。

  • Dart 3.0 Sound Null Safety 2023 年 5 月发布,引入了强制的空安全(Sound Null Safety),引入了新的核心功能记录(Records) 模式(Patterns),这些特性简化了复杂数据结构的处理,并使代码更加具有表达力。类修饰符(Class Modifiers) ,则提供了更多控制类行为和继承的能力。

执行方式

目前Dart有三种方式执行:一是在原生的虚拟机上,二是将Dart代码转成Javascript,直接在Javascript引擎上执行,三是将其编译为可执行文件并执行。

支持与生态

丰富开发工具与文档
  • 支持Android Studio、IntelliJ IDEA、WebStorm的JetBrains工具套件,
  • 支持带有Dart Code扩展名的Visual Studio Code。
  • 可以让你在任何现代化的浏览器中体验 Dart 编程语言线上工具DartPad 已针对Dart 2进行了全面更新。

  • Web工具基于新的构建系统,可以快速,可调试和可扩展。如生成序列化代码,

  • 附带了包管理器,静态的分析工具,网页文档,dart风格编程指南。
增长快速

在过去的一年中,Dart取得了惊人的增长。 google的分析表明,外部使用量增长了十倍。 从拉取请求的角度来看,在最后一个季度,Dart是GitHub上增长最快的语言之一。 StackOverflow问题的增长也生动地展示了Dart的发展势头

大量使用

Dart是Google用于Web应用程序开发的几种语言之一,它来自数十个不同项目的数百万行代码,

  • Blossom, Montage, Soundtrap, Mandrill, 谷歌内部 CRM 应用 and Google Elections Google Ads,Google Shopping和Dart基础架构团队。

    最大的广告之一是Google Ads,它为数十亿美元的网络经济提供动力。在将代码迁移到Dart的过程中,他们将UI代码库的大小减少了40%,同时提高了开发人员的生产力和应用程序质量。

  • Flutter 2018年12月4日,谷歌发布Flutter 1.0版本,Flutter是谷歌开源的移动应用开发SDK,其最大的特点就是一套代码多平台运行、高性能和Hot Reload(热重载)。Flutter采用Dart作为其底层语言。
  • Fuchsia 谷歌即将发布Fuchsia系统就以Flutter为主要开发框架。

Dart也由于Flutter美好未来而得到众多开发者的青睐。

Dart概述

Dart通常情况下运行在DartVM上,但是在特定情况下它也可以编译成本地代码运行在硬件上,比如Flutter会将代码编译成指定平台的本地代码来提高性能。

Dart的特性主要有以下几点

  • 执行速度快,Dart同时支持JIT(Just In Time,即时编译)和AOT(Ahead of Time,运行前编译)两种编译模式。

    JIT 在运行时即时编译,在开发周期中使用,可以动态下发和执行代码,开发测试效率高,但运行速度和执行性能则会因为运行时即时编译受到影响。 AOT 即提前编译,可以生成被直接执行的二进制代码,运行速度快、执行性能表现好,但每次执行前都需要提前编译,开发测试效率低。 Flutter在开发期使用JIT编译,可以缩短产品的开发周期,例如热重载就是基于该特性。在发布期使用AOT,具有运行速度快、执行性能好的特点。

  • 易于移植,Dart可编译成ARM和X86代码,这样Dart可以在Android、iOS和其他地方运行。

  • 容易上手,Dart充分吸收了高级语言特性,如果你已经熟悉C++、C、Java,可以在短短几天内用Dart来开发。

  • 易于阅读,Dart使Flutter不需要单独的声明式布局语言(XML或JSX),或者单独的可视化界面构建器,这是因为Dart的声明式编程布局易于阅读。

  • 避免抢占式调度,Dart可以在没有锁的情况下进行对象分配和垃圾回收。像JavaScript一样,Dart避免了抢占式调度和共享内存,大多数支持并发执行线程的计算机语言(Java、Kotlin、Swift)都使用抢占式来切换线程,抢占就会产生竞态条件,竞态条件很有可能导致严重错误,如应用程序崩溃导致数据丢失等等,一般解决竞态条件使用锁来保护,但是锁本身可能导致卡顿,也有可能产生死锁,而Dart针对这个问题,采取了isolate方法来解决,Dart中的线程称为isolate,不共享内存。那么Dart是单线程的,意味根本不允许抢占。单线程有助于开发者确保关键功能(动画和转场)完成而无需抢占。 Flutter应用程序被编译为本地代码,因此它们不需要再领域之间建立缓慢的桥梁,所以启动速度快得多。

Dart的重要概念有以下几点:

  • 在Dart中,一切都是对象,每个对象都是一个类的实例,所有对象都继承自Object。

  • Dart在运行前解析所有的代码,指定数据类型和编译时常量,可以使代码运行的更快。

  • 与Java不同,Dart不具备关键字public、protected、private。如果一个标识符以下划线_开始,那么它和它的库都是私有的。

  • Dart支持顶级的函数如main(),也支持类或对象的静态和实例方法,还可以在函数内部创建函数。

  • Dart支持顶级的变量,也支持类或对象的静态变量和实例变量,实例变量有时称为字段或属性。

  • Dart支持泛型类型,如List(整数列表)或List(任何类型的对象列表)。

  • Dart工具可以报告两种问题:警告和错误。警告只是说明代码可能无法正常工作,但不会阻止程序执行。错误可以是编译时或运行时的。编译时错误会阻止代码执行; 运行时错误会导致代码执行时报出异常。

  • 任何保存在变量中的都是一个 对象 , 并且所有的对象都是对应一个 类 的实例。 无论是数字,函数和 null 都是对象。所有对象继承自 Object 类。

  • 尽管 Dart 是强类型的,但是 Dart 可以推断类型,所以类型注释是可选的。 如果要明确说明不需要任何类型, 使用特殊类型var dynamic 。

  • 标识符 以字母或下划线(_)开头,后跟任意字母和数字组合。

内存分配与垃圾回收

Dart VM的内存分配策略为,创建对象时只需要在堆上移动指针,内存增长始终是线性的,省去了查找可用内存的过程。

在Dart中,并发是通过Isolate实现的。Isolate是类似于线程但不共享内存,独立运行的worker。这样的机制,就可以让Dart实现无锁的快速分配。

Dart的垃圾回收采用多生代算法。新生代在回收内存时采用“半空间”机制,出发垃圾回收时,Dart会将当前半空间中的“活跃”对象拷贝到备用控件,然后整体释放当前空间的所有内存。回收过程中,Dart只需要操作少量的“活跃”对象,没有引用的大量“死亡”对象则被忽略,这样的回收机制很适合Flutter框架中大量Widget销毁重建的场景。

单线程

Dart是单线程模型,不存在资源竞争和状态同步的问题。这就意味着,一旦某个函数开始执行,就将执行到这个函数结束,而不会被其他Dart代码打断。

Dart中并没有线程,只有Isolate(隔离区)。Isolates之前不会共享内存,就像几个运行在不同进程中的worker,通过事件循环(Event Looper)在事件队列(Event Queue)上传递消息通信。

一个简单的dart程序

1
2
3
4
5
6
7
8
9
10
// 定义一个函数
printInteger(int aNumber) {
  print('The number is $aNumber.'); // 打印到控制台。
}

// 应用从这里开始执行。
main() {
  var number = 42; // 声明并初始化一个变量。
  printInteger(number); // 调用函数。
}
本文由作者按照 CC BY 4.0 进行授权