Flutter为什么选择Dart?

Dart是Google于2011年发布的编程语言,旨在解决JavaScript的问题。它支持JIT和AOT编译,提供高效的内存管理和无锁并发。Flutter框架使得Dart进入移动开发领域,尽管起初发展缓慢,但随着Flutter的流行和Fuchsia的推动,Dart生态系统正在快速发展。Dart的单线程模型、声明式布局以及快速的热重载功能为开发者带来了便捷。随着更多开发者加入,Dart的未来充满潜力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

什么是Dart?

Dart是Google在2011年10月在丹麦召开的GOTO大会上发布的一门新的编程语言。如同 Kotlin 和 Swift 的出现,分别是为了解决 Java 和 Objective-C 在编写应用程序的一些实际问题一样,Dart 的诞生正是要解决 JavaScript 存在的、在语言本质上无法改进的缺陷。
那么JavaScript具有什么特性呢?
JavaScript 之父布兰登 · 艾克(Brendan Eich)曾在一次采访中说,JavaScript“几天就设计出来了”。
概括来说,他的设计思路是这样的:
借鉴 C 语言的基本语法;
借鉴 Java 语言的数据类型和内存管理机制;
借鉴 Scheme 语言,将函数提升到“第一等公民”(first class)的地位;
借鉴 Self 语言,使用基于原型(prototype)的继承机制。
所以,JavaScript 实际上是两类编程语言风格的混合产物:(简化的)函数式编程风格,与(简化的)面向对象编程风格。
由于设计时间太短,一些细节考虑得不够严谨,导致后来很长一段时间,使用 JavaScript 开发的程序混乱不堪。出于对 JavaScript 的不满,Google 的程序员们决定自己写一个新语言来换掉它,所以 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 始终不温不火。
但,Dart 也借此机会开始转型:在 Google 内部孵化了移动开发框架 Flutter,弯道超车进入了移动开发的领域;而在 Google 未来的操作系统 Fuchsia 中,Dart 更是被指定为官方的开发语言。
也正是因为使用者不多、历史包袱少,所以在经历了这么多的故事后,Dart 可以彻底转变思路,成为专注大前端与跨平台生态的语言。
接下来,我们就从 Flutter 开发的视角,聊聊 Dart 最重要的核心特性吧。

Dart的特性:

JIT 与 AOT:借助于先进的工具链和编译器,Dart 是少数同时支持 JIT(Just In Time,即时编译)和 AOT(Ahead of Time,运行前编译)的语言之一。
语言在运行之前通常都需要编译,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 语言的第三方库还很少,并且质量一般,不过值得庆幸的是,因为 Flutter 和 Fuchsia 的推动,Dart SDK 更新迭代的速度快了很多,开发者的热情也急剧增长,Dart 生态增速很快。
从Flutter 自身来看,它的出现提供了一套彻底的跨平台方案,也弥补了当今跨平台开发框架的短板,解决了业界痛点,极有可能成为跨平台开发领域的终极解决方案,前途光明,未来非常值得期待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值