
并且其中的逗号也更新为了分号,请问这个语法特性是什么时候更新的,检索良久未能找到有关信息。
]]>import { serve } from "https://deno.land/std@0.76.0/http/server.ts";
const s = serve({ port: 8000 });
console.log("http://localhost:8000/");
for await (const req of s) {
req.respond({ body: "Hello World\n" });
}
···
······
import 'dart:io';
Future main() async {
var server = await HttpServer.bind(
InternetAddress.loopbackIPv4, 8000); print('Listening on localhost:${server.port}');
await for (HttpRequest request in server) {
request.response.write('Hello world\n'); await request.response.close(); }
}
······
]]>由于 Dart 1 实质上已经被放弃,Dart 2 改动很大几乎就是一种新的语言,因此这里只列出 v2.0 的日期。
一个现象:这些新出的热门语言,都是静态类型语言,其原因可能是现代 IDE 发展起来了。 动态语言最大的优势是 “写起来省键盘”,但在类型推导与现代 IDE 的加持之下, 静态语言写起来不再繁琐,反而动态语言由于更难进行静态分析而难以享受 IDE 提供的更多好处。
言归正传,从上面各语言的日期可见,其中 Dart 2 非常新,这使得它有机会尽情吸收其它语言的经验, 反映出现代编程语言的很多新思想。下面开始说说 Dart 语言的特点。
甚至连数字都是对象,比如下面的例子,数字可直接调用方法:
// int -> String String OneAsString= 1.toString(); assert(OneAsString== '1'); 由于一切皆对象,所以任何变量的默认值都是 null,比如:
int n; String s; assert(n == null); assert(s == null); 直接在代码内写 assert(), 这个函数只在开发环境中有效,而在生产环境中会被忽略,非常适合用来做一些简单但重要的测试。
以前的静态类型语言一般要求每次定义变量时,都明确写明类型,这非常繁琐。 而现在自动推导变量类型这个特性几乎成为了各种新语言的标配,不少老牌语言也在新版中加入这个特性。
var s = 'abc'; assert(s.runtimeType.toString() == 'String'); 不通过 public, protected, private 等关键词来表明成员是否对外公开,而是通过首字母来表示。 类似于 Golang, Golang 是用首字母大写表示 public, 但这被很多开发者诟病,确实会带来一些不便。 而 Dart 则是用首字母为下划线来表示 private, 这就比 Golang 那种设定舒服多了,也很符合直觉。
// 这个例子只是为了说明访问权限,并非最佳实践。 class MyClass { int _count; int get count => _count; set count(value) => _count = value; } 是不是有点像 Python? 但与 Python 不同的是,_count 不是看起来像 private, 而是真的 private !
这也是新语言中比较流行的一种特性,确实非常好用。
int n; // 此时 n == null, 可以赋值。 n ??= 3; assert(n == 3); // 此时 n != null,保留原来的值。 n ??= 5; assert(n == 3); print(1 ?? 3); // 结果为 1. print(null ?? 5); // 结果为 5. myObject?.someProperty // 如果没有问号语法,就会麻烦很多: (myObject != null) ? myObject.someProperty : null 关于 null 有一个故事,他的发明者曾说这是自己犯下的 “十亿美元错误”(billion-dollar mistake)。 但这么多年过去了,新语言明明有机会采用 “无 null” 设计,却还是选择了有 null, 侧面说明这个发明还是好处多过坏处。
比如 filter(在 Dart 里是 where), map, any, fold 等等,以前常见于动态类型语言,但由于这些函数确实很方便, 现在很多静态语言里也是标配特性了。
numbers .where((n) => n % 2 == 0) .forEach((n) => print(n)); 在下面的例子中,x 和 y 拥有默认的 getter 和 setter,非常方便。
class Point { num x, y; Point(this.x, this.y); } var p = Point(1.2, 3); p.y = 2.5; print('${p.x}, ${p.y}'); // "1.2, 2.5" Kotlin 也有类似的特性。为什么在已经有了那么多编程语言的情况下,还要不断发明新的语言呢, 原因之一就是这些新特性非常优雅:写起来更方便,读起来更清晰。
据说是微软 C# 最先发明的 async/await 语法(我没有查证),用过都说好,甚至连 Javascript 和 Python 都在版本升级中加入了这种语法。
在本文开头列出的多种语言之中,Go 由于拥有独特的 goroutine 而不需要 async/await, 另外 Swift 虽然暂时没有这种语法,但开发者呼声很高,后续大概率会加上,列表中的其他语言全都已经具备这种语法了。
Future main() async { var ver = await getVersion(); print('In main: version is $ver'); } 如果你曾经主要使用 Javascript, 后来转到别的语言,那么你可能会很怀念那个可爱又实用的胖箭头。 在 Dart 里你可以再次愉快过使用它。
class MyClass { int value = 0; void increase() => value++; } Dart 自称是专为客户端(约等于前端)而设计的语言,而这个新颖、高效的串联语法很好地体现了什么叫做 客户端语言,这是 Dart 带给我最大的惊喜!
querySelector('#confirm') ..text = 'Confirm' ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!')); 以上列举了 Dart 的一部分特性,可以看出它吸收了很多新特性,同时考虑了别的语言的使用习惯, 学起来会有一种“似曾相识”的熟悉感,用起来会有一种“要啥有啥”的爽感。
再结合它的强大生命力:通过 Flutter 在手机端生存,通过编译为高质量的 Javascript 代码在网页端生存, 通过编译为二进制可执行文件在桌面电脑端生存,同时也已经被 Google 官方确定为 Fuchsia 的主要编程语言之一。 因此,有兴趣的同学不妨学习一下。
]]>这些特性 Python 需要分为多个 List Comprehension 且外层嵌套逻辑来实现,比如产生这样的一个 List:
( Dart 的实现)
void main() { print([ if (2 > 1) 222 else 333, if (2 > 3) 444, for (int i in Iterable.generate(10)) if (i % 3 == 1) i, for (int i in Iterable.generate(10, (x) => x + 100)) if (i % 2 == 0) i ]); } output: [222, 1, 4, 7, 100, 102, 104, 106, 108]
https://dartpad.dev/540d15e9a25afb2159ee1b380e98d906
( Python 的实现)
print( [if (2 > 1) 222 else 333] + ([444] if (2 > 3) else []) + [i for i in range(10) if i % 3 == 1] + [i + 100 for i in range(10) if (i + 100) % 2 == 0] ) ]]>dart 的后端框架
btw,
dart 的 UI 框架
后台管理 UI https://github.com/GeekyAnts/flutter-web-admin-dashbaord https://github.com/HyperionGray/ng_modular_admin https://github.com/kalismeras61/flutter_web_dashboard
]]>import 'dart:async'; main() async{ print("main begin"); a(); print("main end"); } a() async { print("a begin"); await b(); print("a end"); } b() async { print("b begin"); await c(); print("b end"); } Future c() { return new Future(() { print("c"); }); } 上面这段代码的输出结果是:
main begin
a begin
b begin
main end
c
b end
a end
main end 提前执行了,我的理解是,在程序走到 b 函数里面时,一直是在当前线程的,然后遇到 await 语句,等待 c 函数执行完成,所以应该是 c 函数执行完再继续进行下去,请问这样理解有问题吗?
]]>假如有人合作的话,可以添加一些 flutter webrtc 的内容,以及 flutter desktop、web 的内容,使书籍更加丰富与权威。
]]>欢迎关注
]]>