昨天从nodejs站下车,正想往ruby方向走,突然在街角一不起眼处发现了一小屋Dart。Dart曾经了解过,是google开发的用于替代javascript的一门新语言。它的特点是:语法很像java/javascript,可同时运行于server端和client端。它的目标是,让人们可以更快速的开发出更高质量的web程序。
但dart最开始为人们所知时,却是dart运行于客户端时,以生成的js代码巨大无比而闻名。不信看看这个hello world:
https://gist.github.com/1277224
短短的几行helloworld的dart代码,被编译成了17259行js代码,引得无数人围观,也打消了很多人尝试dart的念头。
dart可以编译为js代码,并且采用了与其它语言不同的方式:它首先把所有的基本库转为js代码,不管用没用到,然后再把实际的dart代码转为js。之所以这样,是因为dart本身就定位于一个运行于dart vm的语言:在server端,有不知用什么语言编写的vm;在客户端,有用javascript编写的vm。这样有了vm的基础,再添加新功能就容易的多。
如果是其它语言,肯定不会采用这种方式,但对于google来说,这是一石二鸟之计。因为google有chrome,以后可以直接在chrome上嵌入dart vm。这样做,一方面简化了Dart的工作量,另一方面也成了chrome吸引更多开发者的原因。
幽灵同学发给我的what is dart的电子书,短短20页,介绍了一些dart的特性,比较吸引我,这放在后面再说。这里先介绍一个Dart最吸引我的特性:对json的无比良好的支持。
json现在越来越重要,一方面它是服务器端与浏览器端的首选通信格式,另一方面,如果使用如mongodb或couchdb这样的nosql数据库,更离不开json。如果能在语言层面支持json,会大大简化我们的工具。而dart不仅支持,还远超预期。
首先dart中的各种内置类型,可以很好的表示json格式:
{
“language”: “dart”, // String
“targets”: [“dartium”,“javascript”], // List
“website”: { // Map
“homepage”: “www.dartlang.org”,
“api”: “api.dartlang.org”
}
}
如上,它实际上是dart的一个map,里面的[]是dart的List,其它还有String,num和bool类型,正好与json一一对应。如果想把上面的这个json转为字符串,可以调用内置的json库中的方法:
String jsonStr = JSON.stringify(jsonMap)
如果想把字符串变为map,可调用:
Map json = JSON.parse(str)
仅仅这样,还没什么让人激动的,因为javascript中不就是这么做的吗?
别急,先介绍一下背景知识。Dart同时支持动静态类型。我们在开发时,可以打开静态类型检查,以帮助我们找到错误,在运行时,因为在客户端要运行于javascript之上,所以会以动态类型方式执行。首先看看利用JsonObject类来解析一个json字符串,注意编辑器的警告信息:
可以看到,解析为JsonObject后,可以直接以data.language这样的动态方式来调用它的字段。但是因为JsonObject本身没有那些字符,编译器会提示警告信息:它们不是JsonObject的成员变量。
下面是激动人心的地方。我们可以定义一些类,继承于JsonObject:
interface LanguageWebsite extends JsonObject {
String homepage;
String api;
}
interface Language extends JsonObject {
String language;
List
targets; LanguageWebsite website;
}
这里定义了两个类,它们继承于JsonObject,并且添加了相应的属性。然后。。。
仔细地看上面一段代码,警告不见了。而且,我们居然可以把一个父类赋给一个子类!!
之前得到的还是一个类似于map的JsonObject,而现在得到的一个与json中每个字段都有对应属性的类的对象。从json向对象的转换,以这样完美无可挑剔的方式完成了。可以想到,使用这种方式,与其它系统(如mongodb)交互,根本不需要额外的orm框架,直接在语言级别就搞定了!这可以大大简化不同层之间用于数据交换的代码,真是太好了。
(这是dart类型系统的一个独特的设计,因为我还没有深入,这里只好一笔带过,有兴趣者自行研究。)
这里再看看dart的其它特性:
现在dart已经支持windows/linux/mac,在各种主流系统上运行。它同时提供了基于eclipse的编辑器dart editor,支持语法高亮、错误提示和方法补全(暂未提供代码格式化功能)。下载的dart editor中自带了一个叫dartium的浏览器,它就是chrome+dart vm,用于开发之用。
打开dart editor,可以看到它提供了几个例子,其中第一个很炫。
这是一个可显示时分秒的表,运行于dartium的浏览器上,其炫处在于,每一秒数字变化时,用不到的小球会被弹出来,像一粒粒玻璃球弹在墙壁上地上,不停跳动。球与球之间相碰时,也会有同样的动作。这里来个大点的截图:
这个程序运行于客户端,大约使用了500行dart代码,编译出来的js代码大约4473行(不包括vm)。
这里来自slideshare.net上的某个幻灯片:http://www.slideshare.net/yinhm/dart-intro
可见团队阵容还是相当豪华的。
我今天尝试使用dart来写一个简单的web后台程序,只需要简单的route/session/cookie,与mongodb交互。但在尝试过程中遇到了不少问题,比如dart文档比较缺乏,第三方库比较少,最基本的包管理功能还没有实现。想使用第三方库,必须手动把源代码下载下来,通过源代码直接调用。dart的社区也比较小,可能是因为现在开发团队正在努力实现核心功能,api变化较大,不适合发展社区。举例来说,今天下载的mongo-dart最新提交是前几天的,但却不能在最新的dart sdk上成功编译,是因为dart sdk上某些api已经发生了变化。现在的Dart给人的感觉相当低调,可能与此有关。
总之在尝试过程中,发现遇到的困难比较多,最麻烦之处在于难以快速的找到解决方法,太浪费时间。如果现在使用dart来做项目,可以预见会经常被卡住。经过考虑之后,我打算暂不使用Dart,保持关注即可。等到一个成熟的包管理工具实现了,第三方库会发展起来之后,再使用dart会比较好。
不过还是得说,我非常喜欢dart提供的各特色功能,相比nodejs,有着巨大的优势。我相信等dart发布1.0以后,一定会得到飞速的发展,到时候会吸引大批开发者转到dart下。google真是厉害,dart、golang、angularjs,都非常具有吸引力。
最后在唐古拉山的推荐之下,我打算先试试golang,因为它现在已经比较成熟了,评价也比较好。看看它能否满足我的要求。