Flutter为何使用Dart?

老孟导读:关于Flutter为何使用Dart?这个话题,就像PHP是世界上最好的语言同样,争论历来没有中止过,有不少说法,好比:node

  • Google是为了推广Dart,Dart是亲儿子。
  • Flutter团队和Dart团队相邻,沟通起来更方便。

或许存在这样的考虑,但即便是亲儿子,烂泥也要能扶上墙才行啊,难道你真的以为如此重大的决定是靠这些主观色彩决定的?不可能的,因此Dart必定是有其很是大的优点。git

前言

在Flutter成立之初,Flutter团队评估了10多种语言,Flutter团队从四个主要维度进行评估,并考虑了框架做者,开发人员和最终用户的需求。最终Dart在全部评估维度上得分都很高,而且符合全部要求和标准。程序员

Dart在如下主要标准上赢得了高分:github

  • 开发人员的生产力。Flutter的主要价值主张之一是,它可让开发人员使用相同的代码库为iOS和Android建立应用程序,从而节省了工程资源。使用高效的语言能够进一步加速开发人员,并使Flutter更具吸引力。这对咱们的框架团队和开发人员都很是重要。Flutter的大多数语言都是用与咱们提供给用户的语言相同的语言构建的,所以咱们须要在不牺牲开发人员的框架和小部件的可访问性或可读性的状况下,保持100k的代码行的生产力。
  • 面向对象。对于Flutter,咱们须要一种适合Flutter问题领域的语言:建立视觉用户体验。该行业拥有数十年使用面向对象语言构建用户界面框架的经验。尽管咱们可使用非面向对象的语言,但这将意味着从新发明轮子来解决一些难题。另外,绝大多数开发人员都有面向对象开发的经验,这使得学习Flutter开发方法变得更加容易。
  • 可预测的高性能。借助Flutter,咱们但愿使开发人员可以建立快速,流畅的用户体验。为了实现这一点,咱们须要可以在每一个动画帧中运行大量的最终开发人员代码。这意味着咱们须要一种既能提供高性能又能提供可预测的性能的语言,而又不会致使帧丢失的按期暂停。
  • 快速分配。Flutter框架使用一种功能样式的流程,该流程在很大程度上依赖于基础内存分配器,能够有效地处理短暂的短时间分配。此样式是使用具备此属性的语言开发的,在缺乏此功能的语言中没法有效工做。

Dart

如下是Dart功能的列表,这些功能对于Flutter来讲是必不可少:web

  • Dart是AOT(Ahead Of Time)编译的,编译成快速,可预测的本机代码,几乎全部Flutter均可以用Dart编写。这不只使Flutter更快,并且几乎全部内容(包括全部小部件)均可以自定义。
  • Dart还能够经过JIT(Just In Time)进行编译,以实现异常快速的开发周期和改变游戏规则的工做流(包括Flutter亚秒级有状态热重装)。
  • Dart使建立以60fps运行的平滑动画和过渡更加容易。Dart能够在没有锁的状况下进行对象分配和垃圾回收。与JavaScript同样,Dart避免了抢先式调度和共享内存(从而避免了锁定)。由于Flutter应用程序已编译为本机代码,因此它们不须要在领域之间创建缓慢的桥梁(例如,JavaScript与本机之间)。它们的启动速度也快得多。
  • Dart容许Flutter避免使用像JSX或XML这样的声明式布局语言,也不须要单独的可视化界面构建器,由于Dart的声明式程序化布局易于阅读和可视化。并且,因为全部布局都以一种语言和一种位置显示,所以Flutter能够轻松地提供使布局变得轻松的高级工具。
  • 开发人员发现Dart特别易于学习,由于它具备静态和动态语言用户都熟悉的功能。

并不是全部这些功能都是Dart独有的,可是它们的结合达到了一个甜蜜点,这使得Dart在实施Flutter方面具备独特的功能。如此之多,很难想象Flutter会像没有Dart同样强大。数据库

编译与执行

若是您已经了解静态和动态语言,AOT和JIT编译以及虚拟机等主题,则能够跳过本节。编程

从历史上看,计算机语言已分为两类:静态语言(例如,Fortran或C,其中在编译时静态键入变量)和动态语言(例如,Smalltalk或JavaScript,其中,变量的类型能够在运行时更改)时间)。一般会编译静态语言,以生成目标计算机的本机代码(或汇编代码)程序,这些程序在运行时由硬件直接执行。动态语言由解释器执行,而不会产生机器语言代码。设计模式

固然,后来事情变得更加复杂。虚拟机(VM)的概念变得很流行,它实际上只是一种模仿软件中的硬件机器的高级解释器。虚拟机能够更轻松地将语言移植到新的硬件平台。在这种状况下,VM的输入语言一般是中间语言。例如,一种编程语言(例如Java)被编译成一种中间语言(字节码),而后在VM(JVM)上执行。浏览器

另外,如今有即时(JIT)编译器。JIT编译器会在程序执行期间运行,并进行即时编译。在程序建立期间(运行时以前)执行的原始编译器如今称为提早(AOT)编译器。安全

一般,只有静态语言才适合将AOT编译为本机机器代码,由于机器语言一般须要知道数据的类型,而在动态语言中,类型不是预先固定的。所以,一般会解释动态语言或编译JIT。

在开发过程当中 AOT 编译,开发周期(从更改程序到可以执行程序以查看更改结果的时间)老是很慢。可是 AOT 编译产生的程序能够更可预测地执行,而且运行时不须要停下来分析和编译。AOT 编译的程序也更快地开始执行(由于它们已经被编译)。

相反,JIT编译可提供更快的开发周期,但会致使执行速度较慢或更加不稳定。特别是,JIT编译器的启动时间较慢,由于在程序开始运行时,JIT编译器必须在执行代码以前进行分析和编译。研究代表,若是开始执行须要花费几秒钟的时间,那么不少人就会放弃该应用程序。

以上就是 AOT 和 JIT 相关知识,将 AOT 和 JIT 编译的优势结合起来不是很棒吗?而Dart就是经过支持AOT 和 JIT 两种类型的编译而带来显著的优点。

编译并执行Dart

在研究Dart以前,Dart团队的成员已经在高级编译器和虚拟机上进行了开创性的工做,既针对动态语言(如JavaScript 的V8引擎,针对Smalltalk的Strongtalk)又针对静态语言(如Java 的Hotspot编译器)。他们利用这种经验使Dart在如何进行编译和执行方面异常灵活。

Dart是极少数适合于同时编译AOT和JIT的语言之一。支持这两种编译为Dart和(尤为是Flutter)提供了明显的优点。

在开发过程当中使用JIT编译,使用的编译器特别快。而后,当应用程序准备发布时,将对其进行AOT编译。所以,借助先进的工具和编译器的帮助下,提供一箭双鵰的方案:极快的开发周期,并快速执行和启动时间。

Dart在编译和执行方面的灵活性不止于此。例如,Dart能够编译为JavaScript以便浏览器能够执行。这容许在移动应用程序和Web应用程序之间重复使用代码。开发人员报告说,他们的移动和Web应用程序之间的代码复用率高达70%。经过将Dart编译成本机代码,或编译成JavaScript并将其与node.js结合使用,也能够在服务器上使用Dart 。

最后,Dart还提供了一个独立的VM,该VM使用Dart语言自己做为其中间语言(本质上像解释器同样工做)。

Dart能够有效地编译AOT或JIT,解释或转换为其余语言。Dart的编译和执行不只异常灵活,并且速度特别

有状态热重载

Flutter最受欢迎的功能之一是其极快的热重载。在开发期间,Flutter使用JIT编译器,该编译器一般能够在一秒钟内从新加载并继续执行代码。只要有可能,应用状态就会在每次从新加载时保持不变,所以该应用能够从中断处继续运行。

除非您亲自体验过,不然很难理解真正快速(可靠)的热重载在开发过程当中有多重要。Flutter的热加载功能使尝试新想法或尝试替代方法变得容易得多,极大地促进了创造力。

如下是一位移动应用程序开发人员对Flutter 热重载的评价:

我想测试热重载,因此我改变了颜色,保存修改,结果……就喜欢上它了❤!

这个功能真的很棒。我曾认为 Visual Studio 中编辑和继续(Edit & Continue)很好用,但这简直使人惊叹。有了这个功能,我认为移动开发者的生产力能够提升两倍。

这对我来讲真的是翻天覆地的变化。当我部署代码并花费很长时间时,我分心了,作了其余事情,当我回到模拟器 / 设备时,我就忘了想测试的内容。有什么比花 5 分钟将控件移动 2px 更使人沮丧?有了 Flutter,这再也不存在。

避免卡顿

一个快速的应用程序是伟大的,但流畅的应用程序,甚至更好。即便是超级快的动画,若是看起来很生涩,也会看起来很糟糕。可是,防止卡顿可能很困难,由于因素太多。Dart 有许多功能能够避免许多常见的致使卡顿的因素。

固然,(像任何语言同样)仍然能够在Flutter中编写一个简陋的应用程序。Dart更具可预测性,可帮助开发人员更好地控制其应用的平滑度,从而更轻松地提供最佳的用户体验,无所不能。

Flutter建立的用户界面以60 fps的速度运行,其性能远优于其余跨平台开发框架建立的用户界面。

不只比跨平台应用程序更好,并且与最佳本机应用程序同样好:

用户界面很是流畅……我从未见过如此流畅的Android应用。

AOT汇编和“桥梁”

咱们讨论过一个有助于保持顺畅的特性,那就是 Dart 能 AOT 编译为本地机器码。预编译的 AOT 代码比 JIT 更具可预测性,由于在运行时不须要暂停执行 JIT 分析或编译。

可是,AOT编译代码有一个更大的优点,那就是避免了“ JavaScript桥梁”。当动态语言(例如JavaScript)须要与平台上的本机代码进行互操做时,它们必须经过网桥进行通讯,这会致使上下文切换必须保存大量的状态(可能保存到辅助存储)。这些上下文切换是双重打击,由于它们不只使速度变慢,并且可能致使严重的问题。

注意:即便编译的代码也可能须要与平台代码进行对话的接口,这也能够称为桥接,可是一般比动态语言所需的桥接要快几个数量级。此外,因为Dart容许将小部件之类的内容移入应用程序,所以减小了跨过桥梁的须要。

抢先式调度,时间分片和共享资源

大多数支持多个并发执行线程的计算机语言(包括Java,Kotlin,Objective-C和Swift)都使用抢占线程之间进行切换。每一个线程都分配了一个“执行时间”,若是超过了分配的时间,则使用上下文切换来抢占该线程。可是,若是在更新线程(例如内存)之间共享的资源时发生了抢占,则这会致使争用条件。

竞争情况是双重打击,由于它们可能致使严重的错误,包括使应用程序崩溃并致使数据丢失,并且因为依赖于独立线程的相对时间,所以特别难以查找和修复它们。在调试器中运行应用程序时,竞争条件会中止表现出来,这很常见。

解决争用条件的典型方法是使用防止其余线程执行的锁来保护共享资源,可是锁自己可能会致使棘手甚至更严重的问题(包括死锁饥饿)。

Dart 采起了不一样的方法来解决这个问题。Dart 中的线程称为 isolate,不共享内存,从而避免了大多数锁。isolate 经过在通道上传递消息来通讯,这与 Erlang 中的 actor 或 JavaScript 中的 Web Worker 类似。

Dart和JavaScript同样,都是单线程的,这意味着它根本不容许抢占。相反,线程显式地产生(使用async / await,FuturesStreams)。这使开发人员能够更好地控制执行。单线程可帮助开发人员确保关键功能(包括动画和过渡)在没有抢占的状况下得以执行。这不只对用户界面,并且对于其余客户端-服务器代码,一般都是一个很大的优点。

固然,若是开发人员忘记放弃控制,这可能会延迟其余代码的执行。可是,咱们发现,忘记屈服一般比忘记锁定容易得多(由于很难找到竞争条件)。

对象分配和垃圾回收

形成垃圾的另外一个严重缘由是垃圾收集。确实,这只是访问共享资源(内存)的一种特殊状况,在许多语言中,这都须要使用锁。可是在收集可用内存时,锁可能会阻止整个应用程序运行。可是,Dart几乎能够在没有锁的状况下几乎始终执行垃圾回收。

Dart 使用先进的分代垃圾回收和对象分配方案,该方案对于分配许多短时间对象(对于Flutter 这样的反应式用户界面来讲很是完美,Flutter 为每帧重建不可变视图树)而言很是快。Dart 能够用一个指针凹凸分配一个对象(无需锁定)。这将致使平滑的滚动和动画效果,而不会产生现卡顿。

统一布局

Dart的另外一个好处是Flutter不会在您的程序和其余模板化或布局语言(例如JSX或XML)之间拆分布局,也不须要单独的可视化布局工具。这是用Dart编写的简单Flutter视图:

Center(child:
  Column(children: [
    Text('Hello, World!'),
    Icon(Icons.star, color: Colors.green),
  ])
)复制代码

可是,我知道您可能在想什么- 缺乏专门的布局语言如何被称为优点?但它确实是颠覆性的。这是开发人员在题为“ 为何本机应用程序开发人员应认真看待Flutter ” 的文章中写的。

在 Flutter 里,界面布局直接经过 Dart 编码来定义,不须要使用 XML 或模板语言,也不须要使用可视化设计器之类的工具。

个人预感是,听到这个消息后,大家中的一些人甚至会畏缩一点。表面看来,这也是个人反应。使用视觉工具进行布局难道不是一件容易的事。用代码编写各类约束逻辑会不会使事情变得过于复杂?

结果否则。天啊,它简直让我大开眼界。

答案的第一部分是上面提到的热重载。

这比 Android 的 Instant Run 和任何相似解决方案不知道要领先多少年。对于大型的应用一样适用。如此快的速度,正是 Dart 的优点所在。

实际上,可视化编辑器就变得多余了。我一点都不怀恋 XCode 的自动重布局。

Dart 建立的布局简洁且易于理解,而“超快”的热重载可当即看到结果。这包括布局的非静态部分。

结果,在 Flutter 中进行布局要比在 Android/XCode 中快得多。一旦你掌握了它(我花了几个星期),因为不多发生上下文切换,所以会节省大量的开销。没必要切换到设计模式,选择鼠标并开始点击,而后想是否有些东西必须经过编程来完成,如何实现等等。由于一切都是程序化的。并且这些 API 设计得很是好。它很直观,而且比自动布局 XML 更强大。

例如,下面是一个简单的列表布局,该列表布局以编程方式定义的全部其余项目之间添加了分隔线(水平线):

return new ListView.builder(itemBuilder: (context, i) {
  if (i.isOdd) return new Divider(); 
  // rest of function
});复制代码

在 Flutter 中,不管是静态布局仍是编程布局,全部布局都存在于同一个位置。新的Dart 工具,包括Flutter Inspector 和大纲视图(利用全部的布局定义都在代码里)使复杂而美观的布局更加容易。

Dart是专有语言吗?

不,Dart(如 Flutter)是彻底开源的,具有清楚的许可证,同时也是 ECMA 标准的。Dart 在 Google 内外很受欢迎。在谷歌内部,它是增加最快的语言之一,并被 Adwords、Flutter、 Fuchsia 和其余产品使用;在谷歌外部,Dart 代码库有超过 100 个外部提交者。

Dart开放性的更好指标是Google之外社区的发展。例如,咱们看到来自第三方的Dart文章和视频源源不断(包括Flutter和AngularDart),我在本文中引用了其中的一些。

除了Dart自己的外部提交者以外,公共Dart软件包存储库中还有3000多个软件包,包括Firebase,Redux,RxDart,国际化,加密,数据库,路由,集合等的库。

Dart程序员会容易找到吗?

若是没有不少程序员知道Dart,找到合格的程序员会更困难吗?固然不是,Dart使它更容易找到程序员,由于它是一种很是快速且易于学习的语言。Java,JavaScript,Kotlin,C#或Swift等语言的程序员几乎能够当即在Dart中开始编程。最重要的是,热重载鼓励用户玩Dart并尝试新事物,这使得学习Dart更快,更愉快。

这是一个程序员在题为“ 为何Flutter将在2018年腾飞 ”的文章中所说的:

Dart是用于开发Flutter应用程序的语言,学习起来很容易。Google拥有建立简单,记录良好的语言(例如Go)的经验。到目前为止,对我而言,Dart使我想起了Ruby,这是一种学习的乐趣。它不只适用于移动设备,也适用于Web 开发

另外一篇关于Flutter和Dart的文章,标题为“ 为何要Flutter?而不是框架X?甚至更好,为何我要尽心尽力。

Flutter使用由Google建立的Dart语言,说实话,我不喜欢C#或JAVA之类的强类型语言,但我不知道Dart编写代码的方式为何看起来有所不一样。我写起来很舒服。也许是由于它很是简单易学。

经过普遍的UX研究和测试,Dart专门设计为熟悉且易于学习。例如,在2017年上半年,Flutter团队与八名开发人员进行了UX研究。咱们向他们简要介绍了Flutter,而后将它们松散了一个小时左右,以建立一个简单的视图。全部参与者都可以当即开始编程,即便他们之前从未使用过Dart。他们专一于编写响应式视图,而不是语言。Dart 直接就能上手用了。

最后,一位参与者(在任务中取得了特别大的进步)没有说起该语言,所以咱们询问他们是否意识到本身使用的是哪一种语言。他们不知道。语言不要紧 ; 他们在几分钟内就能够在Dart中编程。

学习新系统的难点一般不是学习语言,而是学习全部编写好的代码的库,框架,工具,模式和最佳实践。并且Dart库和工具都很是出色,而且文档齐全。一篇文章宣称:“做为奖励,他们还很是注意本身的代码库,而且拥有我见过的最好的文档。” 学习Dart只需花不多的精力就能够经过节省学习其他时间的时间来弥补。

做为直接的证据,Google内部的一个大型项目但愿将其移动应用程序移植到iOS。他们打算雇用一些iOS程序员,但决定尝试Flutter。他们监控了使开发人员快速掌握Flutter所花费的时间。他们的结果代表,程序员能够在三周内学习Dart Flutter并提升工做效率。相比之下,他们以前观察到的五个星期可使程序员仅在Android上就能够上手(更不用说他们必须雇用和培训iOS的开发人员)。

最后,文章“ 咱们为何选择Flutter以及它如何使咱们的公司变得更好 ”来自一家将大型企业应用程序迁移到全部三个平台(iOS,Android和Web)上的Dart的公司。他们的结论:

招人变得容易多了。不管他们是来自 Web、iOS 仍是 Android,咱们如今都但愿接受最佳人选。

如今咱们拥有 3 倍的工做效率,由于咱们全部的团队都集中在一个代码库上。

知识共享达到史无前例的高度。

经过使用Dart和Flutter,他们可以将生产力提升三倍。鉴于他们以前所作的事情,这不足为奇。与许多公司同样,他们正在使用独立的语言,工具和程序员为每一个平台(Web,iOS和Android)构建独立的应用程序。改用Dart意味着他们再也不须要雇用三种不一样的程序员。对于他们来讲,将现有的程序员转移到Dart上很容易。

他们和其余人发现,一旦程序员开始使用Flutter,他们一般会爱上Dart。他们喜欢语言的简洁性和缺少仪式感。他们喜欢语言功能,例如级联,命名参数,异步/等待和流。最重要的是,他们喜欢Dart所提供的Flutter功能(例如热重载),而Dart帮助他们构建的漂亮,高性能的应用程序。

秘诀就是专一

Dart 2中的改进集中在优化客户端开发上。可是Dart仍然是构建服务器端,台式机,嵌入式系统或其余程序的绝佳语言。

专一是一件好事。专一于几乎可使全部持久的流行语言受益。例如:

  • C是用于编写操做系统和编译器的系统编程语言。它变得更多了。
  • Java是为嵌入式系统设计的语言。
  • JavaScript是Web浏览器的脚本语言(!)。
  • 甚至备受反对的PHP也成功了,由于它专一于编写“我的主页”(并以此为名)。

另外一方面,许多语言已经明确尝试(但失败)成为彻底通用的语言,例如PL / 1和Ada等。最多见的问题是,没有集中注意力,这些语言就成了众所周知的厨房水槽。

使Dart成为出色的客户端语言的许多功能也使它成为服务器端使用的更好语言。例如,Dart避免了抢先式多任务这一事实使它具备与服务器上的Node相同的优点,但打字效果更好,更安全。

为嵌入式系统编写软件也是如此。Dart可靠地处理多个并发输入的能力是关键。

最后,Dart在客户端上的成功将不可避免地引发更多在服务器上使用它的兴趣-就像JavaScript和Node发生的状况同样。为何要强迫人们使用两种不一样的语言来构建客户端服务器软件?

结论

这对于 Dart 来讲是一个激动人心的时刻。使用 Dart 的人喜欢它,而 Dart 2 中的新特性使其成为你工具库中更有价值的补充。若是您没有使用Dart,但愿本文为您提供有关Dart的新功能或不一样之处的有价值的信息,而且您能够尝试使用它和Flutter。

查看英文原文: https://hackernoon.com/why-flutter-uses-dart-dd635a054ebf

交流

老孟Flutter博客地址(近200个控件用法):laomengit.com

欢迎加入Flutter交流群(微信:laomengit)、关注公众号【老孟Flutter】:

相关文章
相关标签/搜索