囫囵吞桃的个人博客 Home

Dart是一种美丽的语言

#工程 #技术思考

Dart是一种美丽的语言

Dart的历史

Dart最初是Google公司为取代JS而开发一种编译+解释型,强静态类型的编程语言。还曾一度让Chrome支持像运行JS一样,直接运行Dart。

但是JS在web的地位已经根深蒂固,微软推出TS后,更是将JS弱类型的短板给补齐。作为新语言的Dart就更难在web世界抢到自己的一席之地了。

一直直到后来,Google推出了后端框架Flutter,将Dart作为唯一支持的语言,Dart才迎来了自己的第二春。不过可惜的是,Flutter在中国大陆一直是一个很冷门的框架。Google对它的投入也逐年减少。

Dart最初的语法和Java非常类似。甚至可以说是一模一样。大量API都与Java高度相似。直到后来,Dart 3的推出,才让Dart长出了自己的特色。


Dart的美丽之处

语法与开发体验

Dart的语法脱胎于Java,因此与C/CPP高度相似。对于计算机初学者而言,在接触过了C和CPP这两门被视为入门必学的语言后,再去接触Dart,上手难度极低。

void main()
{
	print("Hello, World!");
}

Dart 3开始,也融入了一些模仿TS的特性。如其lambda函数可以写的非常漂亮。

()=>"haha";

此外,Dart也解决了C和CPP中大量的历史包袱。不需要区分头文件和源代码,不需要费心于极其麻烦的构建配置。

此外,Dart是一门有GC的语言。不会像C和CPP那样稍有不慎就会造成内存安全问题。

奇妙的构建目标

一般而言,一门语言通常要么是编译型语言,要么是解释型语言。前者运行效率高,而编译时间长;后者编译时间短(甚至可能不需要任何编译),但牺牲了一定的运行效率。

编译时间过长,对开发者来说相当痛苦。每一次调整程序都要经过漫长的等待。即使有增量编译,编译型语言程序启动花的时间还是不如可以点击即运行的解释型语言快。

C和CPP是典型的编译型语言,Python是典型的解释型语言。而Java、C#比较特殊,先编译成中间语言,再由运行时JVM、.NET解释运行。

而Dart,同时支持编译和解释运行。可以选择,在发布时,编译成机器码,以追求极致的运行效率。在调试时,则通过Dart VM解释运行。

此外,Dart的编译,支持编译为目标设备的机器码。在其争夺web地位之时,官方也为其提供了编译成JS的能力。

不过,需要补充和强调的是:Dart编译后的程序,通常比原生方案更大更臃肿。写一个输出Helloworld,编译成机器码,要比C/CPP版本的大得多;编译成JS,也比纯JS版本多几千行代码。

主要原因是因为,编译后的产物里还包含了Dart的运行时,以维持GC等能力。不过,这个运行时随构建产物发行,的确不需要用户再额外安装类似JVM、.NET Runtime这样的运行时组件。

遗憾

令人遗憾的是,Flutter现在仍是一个比较冷门的后端框架。其主打win、macOS、linux、iOS、android、web全平台支持。但是多数人只用来开发iOS和Android跨平台app。其开发桌面端应用,也不如其他方案好用,体感上它更倾向于是一个顺带支持桌面端的移动端app框架。它甚至一度不支持多窗口。

而web方面,最初的技术底层是编译为JS再运行。但后来改为了wasm。不过几年来,长期还只是一个试验性方案。

由于其作为wasm应用,web端的使用体验和使用传统的JS生态下的前端框架开发的网页很不一样,这一点被一些web开发者所诟病。第一次进入可能会有很长的加载时间。页面跳转也不能用路径参数,否则会让页面重新加载。

与此同时,KMP等react native等其他的跨平台移动端app方案也在出现,开始挑战Flutter的地位。不过,Flutter的画面渲染采用Google自演的skia引擎,可以在不同的平台上做到像素级一致,这一点优势是其他方案所不能比拟的。

Dart虽然能编译成机器码,但是其性能一直不如其他语言,很大原因是因为其臃肿的运行时。