加载中...

dart


其中 Y=dart

源代码下载: learndart-cn.dart

Dart 是编程语言王国的新人。 它借鉴了许多其他主流语言,并且不会偏离它的兄弟语言 JavaScript 太多。 就像 JavaScript 一样,Dart 的目标是提供良好的浏览器集成。

Dart 最有争议的特性必然是它的可选类型。

  1. import "dart:collection";
  2. import "dart:math" as DM;
  3. // 欢迎进入15分钟的 Dart 学习。 http://www.dartlang.org/
  4. // 这是一个可实际执行的向导。你可以用 Dart 运行它
  5. // 或者在线执行! 可以把代码复制/粘贴到这个网站。 http://try.dartlang.org/
  6. // 函数声明和方法声明看起来一样。
  7. // 函数声明可以嵌套。声明使用这种 name() {} 的形式,
  8. // 或者 name() => 单行表达式; 的形式。
  9. // 右箭头的声明形式会隐式地返回表达式的结果。
  10. example1() {
  11. example1nested1() {
  12. example1nested2() => print("Example1 nested 1 nested 2");
  13. example1nested2();
  14. }
  15. example1nested1();
  16. }
  17. // 匿名函数没有函数名。
  18. example2() {
  19. example2nested1(fn) {
  20. fn();
  21. }
  22. example2nested1(() => print("Example2 nested 1"));
  23. }
  24. // 当声明函数类型的参数的时候,声明中可以包含
  25. // 函数参数需要的参数,指定所需的参数名即可。
  26. example3() {
  27. example3nested1(fn(informSomething)) {
  28. fn("Example3 nested 1");
  29. }
  30. example3planB(fn) { // 或者不声明函数参数的参数
  31. fn("Example3 plan B");
  32. }
  33. example3nested1((s) => print(s));
  34. example3planB((s) => print(s));
  35. }
  36. // 函数有可以访问到外层变量的闭包。
  37. var example4Something = "Example4 nested 1";
  38. example4() {
  39. example4nested1(fn(informSomething)) {
  40. fn(example4Something);
  41. }
  42. example4nested1((s) => print(s));
  43. }
  44. // 下面这个包含 sayIt 方法的类声明,同样有一个可以访问外层变量的闭包,
  45. // 就像前面的函数一样。
  46. var example5method = "Example5 sayIt";
  47. class Example5Class {
  48. sayIt() {
  49. print(example5method);
  50. }
  51. }
  52. example5() {
  53. // 创建一个 Example5Class 类的匿名实例,
  54. // 并调用它的 sayIt 方法。
  55. new Example5Class().sayIt();
  56. }
  57. // 类的声明使用这种形式 class name { [classBody] }.
  58. // classBody 中可以包含实例方法和变量,
  59. // 还可以包含类方法和变量。
  60. class Example6Class {
  61. var example6InstanceVariable = "Example6 instance variable";
  62. sayIt() {
  63. print(example6InstanceVariable);
  64. }
  65. }
  66. example6() {
  67. new Example6Class().sayIt();
  68. }
  69. // 类方法和变量使用 static 关键词声明。
  70. class Example7Class {
  71. static var example7ClassVariable = "Example7 class variable";
  72. static sayItFromClass() {
  73. print(example7ClassVariable);
  74. }
  75. sayItFromInstance() {
  76. print(example7ClassVariable);
  77. }
  78. }
  79. example7() {
  80. Example7Class.sayItFromClass();
  81. new Example7Class().sayItFromInstance();
  82. }
  83. // 字面量非常方便,但是对于在函数/方法的外层的字面量有一个限制,
  84. // 类的外层或外面的字面量必需是常量。
  85. // 字符串和数字默认是常量。
  86. // 但是 array 和 map 不是。他们需要用 "const" 声明为常量。
  87. var example8A = const ["Example8 const array"],
  88. example8M = const {"someKey": "Example8 const map"};
  89. example8() {
  90. print(example8A[0]);
  91. print(example8M["someKey"]);
  92. }
  93. // Dart 中的循环使用标准的 for () {} 或 while () {} 的形式,
  94. // 以及更加现代的 for (.. in ..) {} 的形式, 或者
  95. // 以 forEach 开头并具有许多特性支持的函数回调的形式。
  96. var example9A = const ["a", "b"];
  97. example9() {
  98. for (var i = 0; i < example9A.length; i++) {
  99. print("Example9 for loop '${example9A[i]}'");
  100. }
  101. var i = 0;
  102. while (i < example9A.length) {
  103. print("Example9 while loop '${example9A[i]}'");
  104. i++;
  105. }
  106. for (var e in example9A) {
  107. print("Example9 for-in loop '${e}'");
  108. }
  109. example9A.forEach((e) => print("Example9 forEach loop '${e}'"));
  110. }
  111. // 遍历字符串中的每个字符或者提取其子串。
  112. var example10S = "ab";
  113. example10() {
  114. for (var i = 0; i < example10S.length; i++) {
  115. print("Example10 String character loop '${example10S[i]}'");
  116. }
  117. for (var i = 0; i < example10S.length; i++) {
  118. print("Example10 substring loop '${example10S.substring(i, i + 1)}'");
  119. }
  120. }
  121. // 支持两种数字格式 int 和 double 。
  122. example11() {
  123. var i = 1 + 320, d = 3.2 + 0.01;
  124. print("Example11 int ${i}");
  125. print("Example11 double ${d}");
  126. }
  127. // DateTime 提供了日期/时间的算法。
  128. example12() {
  129. var now = new DateTime.now();
  130. print("Example12 now '${now}'");
  131. now = now.add(new Duration(days: 1));
  132. print("Example12 tomorrow '${now}'");
  133. }
  134. // 支持正则表达式。
  135. example13() {
  136. var s1 = "some string", s2 = "some", re = new RegExp("^s.+?g\$");
  137. match(s) {
  138. if (re.hasMatch(s)) {
  139. print("Example13 regexp matches '${s}'");
  140. } else {
  141. print("Example13 regexp doesn't match '${s}'");
  142. }
  143. }
  144. match(s1);
  145. match(s2);
  146. }
  147. // 布尔表达式必需被解析为 true 或 false,
  148. // 因为不支持隐式转换。
  149. example14() {
  150. var v = true;
  151. if (v) {
  152. print("Example14 value is true");
  153. }
  154. v = null;
  155. try {
  156. if (v) {
  157. // 不会执行
  158. } else {
  159. // 不会执行
  160. }
  161. } catch (e) {
  162. print("Example14 null value causes an exception: '${e}'");
  163. }
  164. }
  165. // try/catch/finally 和 throw 语句用于异常处理。
  166. // throw 语句可以使用任何对象作为参数。
  167. example15() {
  168. try {
  169. try {
  170. throw "Some unexpected error.";
  171. } catch (e) {
  172. print("Example15 an exception: '${e}'");
  173. throw e; // Re-throw
  174. }
  175. } catch (e) {
  176. print("Example15 catch exception being re-thrown: '${e}'");
  177. } finally {
  178. print("Example15 Still run finally");
  179. }
  180. }
  181. // 要想有效地动态创建长字符串,
  182. // 应该使用 StringBuffer。 或者 join 一个字符串的数组。
  183. example16() {
  184. var sb = new StringBuffer(), a = ["a", "b", "c", "d"], e;
  185. for (e in a) { sb.write(e); }
  186. print("Example16 dynamic string created with "
  187. "StringBuffer '${sb.toString()}'");
  188. print("Example16 join string array '${a.join()}'");
  189. }
  190. // 字符串连接只需让相邻的字符串字面量挨着,
  191. // 不需要额外的操作符。
  192. example17() {
  193. print("Example17 "
  194. "concatenate "
  195. "strings "
  196. "just like that");
  197. }
  198. // 字符串使用单引号或双引号做分隔符,二者并没有实际的差异。
  199. // 这种灵活性可以很好地避免内容中需要转义分隔符的情况。
  200. // 例如,字符串内容里的 HTML 属性使用了双引号。
  201. example18() {
  202. print('Example18 <a href="etc">'
  203. "Don't can't I'm Etc"
  204. '</a>');
  205. }
  206. // 用三个单引号或三个双引号表示的字符串
  207. // 可以跨越多行,并且包含行分隔符。
  208. example19() {
  209. print('''Example19 <a href="etc">
  210. Example19 Don't can't I'm Etc
  211. Example19 </a>''');
  212. }
  213. // 字符串可以使用 $ 字符插入内容。
  214. // 使用 $ { [expression] } 的形式,表达式的值会被插入到字符串中。
  215. // $ 跟着一个变量名会插入变量的值。
  216. // 如果要在字符串中插入 $ ,可以使用 \$ 的转义形式代替。
  217. example20() {
  218. var s1 = "'\${s}'", s2 = "'\$s'";
  219. print("Example20 \$ interpolation ${s1} or $s2 works.");
  220. }
  221. // 可选类型允许作为 API 的标注,并且可以辅助 IDE,
  222. // 这样 IDE 可以更好地提供重构、自动完成和错误检测功能。
  223. // 目前为止我们还没有声明任何类型,并且程序运行地很好。
  224. // 事实上,类型在运行时会被忽略。
  225. // 类型甚至可以是错的,并且程序依然可以执行,
  226. // 好像和类型完全无关一样。
  227. // 有一个运行时参数可以让程序进入检查模式,它会在运行时检查类型错误。
  228. // 这在开发时很有用,但是由于增加了额外的检查会使程序变慢,
  229. // 因此应该避免在部署时使用。
  230. class Example21 {
  231. List<String> _names;
  232. Example21() {
  233. _names = ["a", "b"];
  234. }
  235. List<String> get names => _names;
  236. set names(List<String> list) {
  237. _names = list;
  238. }
  239. int get length => _names.length;
  240. void add(String name) {
  241. _names.add(name);
  242. }
  243. }
  244. void example21() {
  245. Example21 o = new Example21();
  246. o.add("c");
  247. print("Example21 names '${o.names}' and length '${o.length}'");
  248. o.names = ["d", "e"];
  249. print("Example21 names '${o.names}' and length '${o.length}'");
  250. }
  251. // 类的继承形式是 class name extends AnotherClassName {} 。
  252. class Example22A {
  253. var _name = "Some Name!";
  254. get name => _name;
  255. }
  256. class Example22B extends Example22A {}
  257. example22() {
  258. var o = new Example22B();
  259. print("Example22 class inheritance '${o.name}'");
  260. }
  261. // 类也可以使用 mixin 的形式 :
  262. // class name extends SomeClass with AnotherClassName {}.
  263. // 必需继承某个类才能 mixin 另一个类。
  264. // 当前 mixin 的模板类不能有构造函数。
  265. // Mixin 主要是用来和辅助的类共享方法的,
  266. // 这样单一继承就不会影响代码复用。
  267. // Mixin 声明在类定义的 "with" 关键词后面。
  268. class Example23A {}
  269. class Example23Utils {
  270. addTwo(n1, n2) {
  271. return n1 + n2;
  272. }
  273. }
  274. class Example23B extends Example23A with Example23Utils {
  275. addThree(n1, n2, n3) {
  276. return addTwo(n1, n2) + n3;
  277. }
  278. }
  279. example23() {
  280. var o = new Example23B(), r1 = o.addThree(1, 2, 3),
  281. r2 = o.addTwo(1, 2);
  282. print("Example23 addThree(1, 2, 3) results in '${r1}'");
  283. print("Example23 addTwo(1, 2) results in '${r2}'");
  284. }
  285. // 类的构造函数名和类名相同,形式为
  286. // SomeClass() : super() {}, 其中 ": super()" 的部分是可选的,
  287. // 它用来传递参数给父类的构造函数。
  288. class Example24A {
  289. var _value;
  290. Example24A({value: "someValue"}) {
  291. _value = value;
  292. }
  293. get value => _value;
  294. }
  295. class Example24B extends Example24A {
  296. Example24B({value: "someOtherValue"}) : super(value: value);
  297. }
  298. example24() {
  299. var o1 = new Example24B(),
  300. o2 = new Example24B(value: "evenMore");
  301. print("Example24 calling super during constructor '${o1.value}'");
  302. print("Example24 calling super during constructor '${o2.value}'");
  303. }
  304. // 对于简单的类,有一种设置构造函数参数的快捷方式。
  305. // 只需要使用 this.parameterName 的前缀,
  306. // 它就会把参数设置为同名的实例变量。
  307. class Example25 {
  308. var value, anotherValue;
  309. Example25({this.value, this.anotherValue});
  310. }
  311. example25() {
  312. var o = new Example25(value: "a", anotherValue: "b");
  313. print("Example25 shortcut for constructor '${o.value}' and "
  314. "'${o.anotherValue}'");
  315. }
  316. // 可以在大括号 {} 中声明命名参数。
  317. // 大括号 {} 中声明的参数的顺序是随意的。
  318. // 在中括号 [] 中声明的参数也是可选的。
  319. example26() {
  320. var _name, _surname, _email;
  321. setConfig1({name, surname}) {
  322. _name = name;
  323. _surname = surname;
  324. }
  325. setConfig2(name, [surname, email]) {
  326. _name = name;
  327. _surname = surname;
  328. _email = email;
  329. }
  330. setConfig1(surname: "Doe", name: "John");
  331. print("Example26 name '${_name}', surname '${_surname}', "
  332. "email '${_email}'");
  333. setConfig2("Mary", "Jane");
  334. print("Example26 name '${_name}', surname '${_surname}', "
  335. "email '${_email}'");
  336. }
  337. // 使用 final 声明的变量只能被设置一次。
  338. // 在类里面,final 实例变量可以通过常量的构造函数参数设置。
  339. class Example27 {
  340. final color1, color2;
  341. // 更灵活一点的方法是在冒号 : 后面设置 final 实例变量。
  342. Example27({this.color1, color2}) : color2 = color2;
  343. }
  344. example27() {
  345. final color = "orange", o = new Example27(color1: "lilac", color2: "white");
  346. print("Example27 color is '${color}'");
  347. print("Example27 color is '${o.color1}' and '${o.color2}'");
  348. }
  349. // 要导入一个库,使用 import "libraryPath" 的形式,或者如果要导入的是
  350. // 核心库使用 import "dart:libraryName" 。还有一个称为 "pub" 的包管理工具,
  351. // 它使用 import "package:packageName" 的约定形式。
  352. // 看下这个文件顶部的 import "dart:collection"; 语句。
  353. // 导入语句必需在其它代码声明之前出现。IterableBase 来自于 dart:collection 。
  354. class Example28 extends IterableBase {
  355. var names;
  356. Example28() {
  357. names = ["a", "b"];
  358. }
  359. get iterator => names.iterator;
  360. }
  361. example28() {
  362. var o = new Example28();
  363. o.forEach((name) => print("Example28 '${name}'"));
  364. }
  365. // 对于控制流语句,我们有:
  366. // * 必需带 break 的标准 switch 语句
  367. // * if-else 和三元操作符 ..?..:..
  368. // * 闭包和匿名函数
  369. // * break, continue 和 return 语句
  370. example29() {
  371. var v = true ? 30 : 60;
  372. switch (v) {
  373. case 30:
  374. print("Example29 switch statement");
  375. break;
  376. }
  377. if (v < 30) {
  378. } else if (v > 30) {
  379. } else {
  380. print("Example29 if-else statement");
  381. }
  382. callItForMe(fn()) {
  383. return fn();
  384. }
  385. rand() {
  386. v = new DM.Random().nextInt(50);
  387. return v;
  388. }
  389. while (true) {
  390. print("Example29 callItForMe(rand) '${callItForMe(rand)}'");
  391. if (v != 30) {
  392. break;
  393. } else {
  394. continue;
  395. }
  396. // 不会到这里。
  397. }
  398. }
  399. // 解析 int,把 double 转成 int,或者使用 ~/ 操作符在除法计算时仅保留整数位。
  400. // 让我们也来场猜数游戏吧。
  401. example30() {
  402. var gn, tooHigh = false,
  403. n, n2 = (2.0).toInt(), top = int.parse("123") ~/ n2, bottom = 0;
  404. top = top ~/ 6;
  405. gn = new DM.Random().nextInt(top + 1); // +1 because nextInt top is exclusive
  406. print("Example30 Guess a number between 0 and ${top}");
  407. guessNumber(i) {
  408. if (n == gn) {
  409. print("Example30 Guessed right! The number is ${gn}");
  410. } else {
  411. tooHigh = n > gn;
  412. print("Example30 Number ${n} is too "
  413. "${tooHigh ? 'high' : 'low'}. Try again");
  414. }
  415. return n == gn;
  416. }
  417. n = (top - bottom) ~/ 2;
  418. while (!guessNumber(n)) {
  419. if (tooHigh) {
  420. top = n - 1;
  421. } else {
  422. bottom = n + 1;
  423. }
  424. n = bottom + ((top - bottom) ~/ 2);
  425. }
  426. }
  427. // 程序的唯一入口点是 main 函数。
  428. // 在程序开始执行 main 函数之前,不期望执行任何外层代码。
  429. // 这样可以帮助程序更快地加载,甚至仅惰性加载程序启动时需要的部分。
  430. main() {
  431. print("Learn Dart in 15 minutes!");
  432. [example1, example2, example3, example4, example5, example6, example7,
  433. example8, example9, example10, example11, example12, example13, example14,
  434. example15, example16, example17, example18, example19, example20,
  435. example21, example22, example23, example24, example25, example26,
  436. example27, example28, example29, example30
  437. ].forEach((ef) => ef());
  438. }

延伸阅读

Dart 有一个综合性网站。它涵盖了 API 参考、入门向导、文章以及更多, 还包括一个有用的在线试用 Dart 页面。 http://www.dartlang.org/ http://try.dartlang.org/


还没有评论.