Dart是一个怎样的语言?



这几天看到一篇新闻 – 白兼容了?Google 正在为 Android 准备一个去 Java 化的 Dart 应用运行框架,对与新闻的标题和内容无力吐槽,不做评论。但是Google推出 sky 似乎证明了native的开发方式越来越向web方式靠近的趋势,最近比较火的要数 react-native 了,他们的原理是类似的,都是先构造一个 virtual dom tree,然后只更新发生变化的 dom。sky 的 readme 也说自己参考了 react,那两者最大的区别应该是开发语言了,react-native 是 javascript,而 Google 用的是自己的亲儿子 – Dart

The Sky framework

Node.js 推出后统一了前后端,如今 node 开发真可谓炙手可热。Google 当初推出 Dart 也是为了统一前后端开发,但是这两年一直不温不火,好像国内使用 Polymer 的开发者也不多,现在用 突然宣布说用 Dart 替换 Android 的开发语言 java,而且还举办了第一个第一届 Dart Developer Summit,看来 Google 准备在 Dart 上发力了,相信 Dart 会是五月底 Google IO 大会上的一个重要议题。
趁着今天放假,跟着 Dart 官网的教程玩了一下 Dart,发现 Dart 这门语言确实不错。


引用包

包的引用方式与 Python 和 Go 类似,都是用 import

import 'dart:html';

不过只导入包的某个组件的方式比较特殊:

import 'dart:math' show Random;
import 'dart:convert' show JSON;
import 'dart:async' show Future;

变量

Dart 与 Python 一样是一个强类型语言

Dart 的变量类型是可选的,叫做 static type annotations。

Dart’s optional types are static type annotations that act as documentation, clearly expressing your intent. 
static final Random indexGen = new Random();
String _firstName;
String _appellation;

Dart 没有 private 关键字,如果变量或方法是私有类型,需要在名称前面加上下划线。

私有变量

class PirateName {
  # ...
  String _firstName;
  String _appellation;
  # ...
}

私有方法

static _parsePirateNamesFromJSON(String jsonString) {
  Map pirateNames = JSON.decode(jsonString);
  names = pirateNames['names'];
  appellations = pirateNames['appellations'];
}

类型转换

Dart 用关键字 as 来做类型转换。

void updateBadge(Event e) {
  String inputName = (e.target as InputElement).value;
}

方法

对于某些特定方法,Dart 提供了语法糖,写法很简单。例如,表达式的值即为返回值的情况,可以这么写:

String toString() => pirateName;

不用写成这样:

String toString() {
  return pirateName;
}

如果是 get 方法,可以直接在返回值类型和方法名之间加上一个关键词 get,而且方法名不需要加括号,调用的时候也不需要加括号。

String get jsonString => JSON.encode({"f": _firstName, "a": _appellation});

String get pirateName =>
    _firstName.isEmpty ? '' : '$_firstName the $_appellation';

级联操作符(…)

级联操作符(The cascade operator (…))可以允许在一个成员变量上执行多个操作。

genButton..disabled = false
         ..text = 'Aye! Gimme a name!';

以上语句就等价于

genButton.disabled = false;
genButton.text = 'Aye! Gimme a name!';

字符串转换

Dart 中变量转化成字符串比 Java 方便多了,跟 Python 有一拼,直接在变量名前加上$符号就可以了。

'$_firstName the $_appellation';

构造方法

Dart 支持有名字的构造方法,这一点比 Java 和 Python 都先进。

PirateName.fromJSON(String jsonString) {
  Map storedName = JSON.decode(jsonString);
  _firstName = storedName['f'];
  _appellation = storedName['a'];
}

这里 PirateName.fromJSON 是一个整体,用的时候要写全了。

return new PirateName.fromJSON(storedName);

参数

跟 Python 一样,Dart 也支持 Optional and Named Arguments,例如参数可以这么写:

PirateName({String firstName, String appellation}) {
  # ...
}

参数要用一个大括号括起来,应该是需要把参数封装成一个类似于 Python 的 Dictionary

但是调用的时候不需要传递所有的参数。

new PirateName(firstName: inputName)

泛型

Dart 支持泛型,这点跟 Java 很像,例如要定义一个 List 变量可以写成这样:

static List names = [];
static List appellations = [];

如果要写明类型,就需要在 List 后的简括后内加上类型。

static List names = [];
static List appellations = [];

关于泛型类型是否像 java 那样支持 superextend还没看到,暂时不知道。


异步操作

Dart 语言原生支持异步操作,主要是用两个关键词 awaitasync
例如,如果我们要定义一个异步方法,不需要像 java 那样去 new Thread,直接在方法后面加上 async 关键字就OK了,这样调用时,该方法时会直接返回一个 Future,caller 无需等待。

static Future readyThePirates() async {
  String path = 'piratenames.json';
  String jsonString = await HttpRequest.getString(path);
  _parsePirateNamesFromJSON(jsonString);    
}

await 跟 java中的 wait 方法用法一样,表示等待,但是它只能用于 async 的方法中。

例如上面代码片段中, await HttpRequest.getString(path) 就表示必须要等到 HttpRequest.getString(path) 返回的 Future 有了最终结果才会继续往下执行 _parsePirateNamesFromJSON(jsonString);


不知道 Dart 支不支持一些高大上的语言特性,比如 闭包(Closure)、Lambda表达式(Lambda expression)、生成器(Generator)等,期待后续的学习。