
                            
                            因收到Google相关通知，网站将会择期关闭。相关通知内容
                            
                            
                            02 预习篇 · Dart语言概览
                            你好，我是陈航。

我们知道，Flutter开发框架采用的开发语言是Dart，所以要用好这个框架，我们必须要搞清楚Dart语言。

关于新技术的学习，一直以来我都非常认同一个观点：千万不要直接陷入细节里，你应该先鸟瞰其全貌，这样才能从高维度理解问题。所以，为了帮助你更高效地掌握Dart，以最快的速度具备开发一款Flutter应用的能力，今天这篇文章，我会先从Flutter开发的角度，和你介绍Dart语言出现的历史背景、特性以及未来。

然后，我会在本专栏的“Dart基础”模块，与你详细分享它的特性、基础语法、类型变量、函数等知识，并和你分享一个使用Dart的综合案例，帮你学懂、学会这门语言。

如果你已经对Dart有一个初步印象了，也可以跳过这篇预习文章，直接学习后面的内容。

Dart是什么？

2011年10月，在丹麦召开的GOTO大会上，Google发布了一种新的编程语言Dart。如同Kotlin和Swift的出现，分别是为了解决Java和Objective-C在编写应用程序的一些实际问题一样，Dart的诞生正是要解决JavaScript存在的、在语言本质上无法改进的缺陷。

那么，JavaScript到底有哪些问题和缺陷呢？JavaScript之父布兰登 · 艾克（Brendan Eich）曾在一次采访中说，JavaScript“几天就设计出来了”。

概括来说，他的设计思路是这样的：


借鉴C语言的基本语法；
借鉴Java语言的数据类型和内存管理机制；
借鉴Scheme语言，将函数提升到“第一等公民”（first class）的地位；
借鉴Self语言，使用基于原型（prototype）的继承机制。


所以，JavaScript实际上是两类编程语言风格的混合产物：（简化的）函数式编程风格，与（简化的）面向对象编程风格。

由于设计时间太短，一些细节考虑得不够严谨，导致后来很长一段时间，使用JavaScript开发的程序混乱不堪。出于对JavaScript的不满，Google的程序员们决定自己写一个新语言来换掉它，所以Dart的最初定位也是一种运行在浏览器中的脚本语言。

而为了推广Dart，Google甚至将自己的Chrome浏览器内置了Dart VM，可以直接高效地运行Dart代码。而对于普通浏览器来说，Google也提供了一套能够将Dart代码编译成JavaScript代码的转换工具。这样一来，开发者们就可以毫无顾虑地使用Dart去开发了，而不必担心兼容问题。再加上出身名门，Dart在一开始就赢得了部分前端开发者的关注。

但，JavaScript的生命力似乎比预想的更强大。

原本JavaScript只能在浏览器中运行，但Node.js的出现让它开始有能力运行在服务端，很快手机应用与桌面应用也成为了JavaScript的宿主容器，一些明星项目比如React、React Native、Vue、Electron、NW（node-webkit）等框架如雨后春笋般崛起，迅速扩展了它的边界。

于是，JavaScript成为了前后端通吃的全栈语言，前端的开发模式也因此而改变，进入了一个新的世界。就如同Atwood定律描述的：凡是能用JavaScript写出来的系统，最终都会用JavaScript写出来（Any application that can be written in JavaScript, will eventually be written in JavaScript.）。

JavaScript因为Node.js焕发了第二春，而Dart就没有那么好的运气了。由于缺少顶级项目的使用，Dart始终不温不火。2015年，在听取了大量开发者的反馈后，Google决定将内置的Dart VM引擎从Chrome移除，这对Dart的发展来说是重大挫折，替代JavaScript就更无从谈起了。

但，Dart也借此机会开始转型：在Google内部孵化了移动开发框架Flutter，弯道超车进入了移动开发的领域；而在Google未来的操作系统Fuchsia中，Dart更是被指定为官方的开发语言。

与此同时，Dart的老本行，浏览器前端的发展也并未停滞。著名的前端框架Angular，除了常见的TS版本外，也在持续迭代对应的Dart版本AngularDart。（不过不得不说的是，这个项目的star一直以来只有可怜的1,100出头）。

也正是因为使用者不多、历史包袱少，所以在经历了这么多的故事后，Dart可以彻底转变思路，成为专注大前端与跨平台生态的语言。

接下来，我们就从Flutter开发的视角，聊聊Dart最重要的核心特性吧。

Dart的特性

每门语言都有各自的特点，适合自己的才是最好的。

作为移动端开发的后来者，Dart语言可以说是集百家之长，拥有其他优秀编程语言的诸多特性和影子，所以对于其他语言的开发者而言，学习成本无疑是非常低的。同时，Dart拥有的特点则恰到好处，在对Flutter的支持上做到了独一无二。所以，Dart成了Flutter的选择。

下面，我就和你详细分享下它的核心特性。

JIT与AOT

借助于先进的工具链和编译器，Dart是少数同时支持JIT（Just In Time，即时编译）和AOT（Ahead of Time，运行前编译）的语言之一。那，到底什么是JIT和AOT呢？

语言在运行之前通常都需要编译，JIT和AOT则是最常见的两种编译模式。


JIT在运行时即时编译，在开发周期中使用，可以动态下发和执行代码，开发测试效率高，但运行速度和执行性能则会因为运行时即时编译受到影响。
AOT即提前编译，可以生成被直接执行的二进制代码，运行速度快、执行性能表现好，但每次执行前都需要提前编译，开发测试效率低。


总结来讲，在开发期使用JIT编译，可以缩短产品的开发周期。Flutter最受欢迎的功能之一热重载，正是基于此特性。而在发布期使用AOT，就不需要像React Native那样在跨平台JavaScript代码和原生Android、iOS代码之间建立低效的方法调用映射关系。所以说，Dart具有运行速度快、执行性能好的特点。

那么，如何区分一门语言究竟是AOT还是JIT呢？通常来说，看代码在执行前是否需要编译即可。如果需要编译，通常属于AOT；如果不需要，则属于JIT。

AOT的典型代表是C/C++，它们必须在执行前编译成机器码；而JIT的代表，则包括了如JavaScript、Python等几乎所有的脚本语言。

内存分配与垃圾回收

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

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

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

单线程模型

支持并发执行线程的高级语言（比如，C++、Java、Objective-C），大都以抢占式的方式切换线程，即：每个线程都会被分配一个固定的时间片来执行，超过了时间片后线程上下文将被抢占后切换。如果这时正在更新线程间的共享资源，抢占后就可能导致数据不同步的问题。

解决这一问题的典型方法是，使用锁来保护共享资源，但锁本身又可能会带来性能损耗，甚至出现死锁等更严重的问题。

这时，Dart是单线程模型的优势就体现出来了，因为它天然不存在资源竞争和状态同步的问题。这就意味着，一旦某个函数开始执行，就将执行到这个函数结束，而不会被其他Dart代码打断。

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

无需单独的声明式布局语言

在Flutter中，界面布局直接通过Dart编码来定义。

Dart声明式编程布局易于阅读和可视化，使得Flutter并不需要类似JSX或XML的声明式布局语言。所有的布局都使用同一种格式，也使得Flutter很容易提供高级工具使布局更简单。

开发过程也不需要可视化界面构建器，因为热重载可以让我们立即在手机上看到运行效果。

Dart的未来

那么，在这样的背景下诞生的Dart，今后发展会怎样呢?

Dart是一个优秀而年轻的现代语言，但一种编程语言并不是搞定了引擎和开发者接口就算完成了，而是必须在这个语言得以立足的库、框架、 应用程序等“生态”都成熟起来之后，其价值才会真正开始体现。而要走到这一步，通常需要花上数年的时间。

目前，基于Dart语言的第三方库还很少，并且质量一般，不过值得庆幸的是，因为Flutter和Fuchsia的推动，Dart SDK更新迭代的速度快了很多，开发者的热情也急剧增长，Dart生态增速很快。

毕竟，在Dart社区目前最顶级的产品就是Flutter和Fuchsia了，因此Dart开发者主要以Flutter开发者居多，当然了也有用Dart开发浏览器前端的开发者，但人数并不多。所以，我觉得Dart是否能够成功，目前来看主要取决于Flutter和Fuchsia能否成功。而，Flutter是构建Fuchsia的UI开发框架，因此这个问题也变成了Flutter能否成功。

正如我在开篇词中提到的，Flutter正式版发布也就半年多的时间，在GitHub上Star就已经超过了68,000，仅落后React Native 10,000左右，可见热度之高。

现在，我们一起回到Flutter自身来看，它的出现提供了一套彻底的跨平台方案，也确实弥补了当今跨平台开发框架的短板，解决了业界痛点，极有可能成为跨平台开发领域的终极解决方案，前途光明，未来非常值得期待。

至此，我们已经可以清晰地看到，Google在遭受与Oracle的Java侵权案后，痛定思痛后下定决心要发展自己的语言生态的布局愿景：Dart凭借Flutter与Fuchsia的生态主攻前端和移动端，而服务端，则有借助于Docker的火热势头增长迅猛的Go语言。

所以说，Google的布局不仅全面，应用和影响也非常广泛，前后端均有杀手级产品用来构建语言生态。相信随着Google新系统Fuchsia的发布，Flutter和Dart会以更迅猛的速度释放它们的力量，而Google统一前后端开发技能栈的愿望也会在一定程度上得以实现。

总结

今天，我带你了解了Dart出现的历史背景，从Flutter开发者的视角详细介绍了Dart语言的各种特性，并分析了Dart的未来发展。

Dart是一门现代语言，集合了各种优秀语言的优点。如果你不了解Dart也无需担心，只要你有过其他编程语言，尤其是Java、JavaScript、Swift或Objective-C编程经验的话，可以很容易地在Dart身上找它们的影子，以极低的成本快速上手。

希望通过这篇文章，你可以先对Dart语言有个初步了解，为我们接下来的学习打好基础。在本专栏的“Dart基础”模块中，我会对照着其他编程语言的特性，和你讲述Dart与它们相似的设计理念，帮助你快速建立起构建Flutter程序的所需要的Dart知识体系。

思考题

对于学习Dart或是其他编程语言，你有什么困扰或者心得吗？

欢迎你在评论区给我留言分享你的经历和观点，我会在下一篇文章中等你！感谢你的收听，也欢迎你把这篇文章分享给更多的朋友一起阅读。

                        
                        
                            