<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] # 簡介 [dart.dev](https://dart.dev/) [dart.cn](https://dart.cn/) 項目地址:https://github.com/dart-lang 目前市面上幾乎沒有 **Dart 2** 相關的書籍,如果你想學習Flutter ,那么Dart ,也就成為了必須要具備的基礎知識,官網就是個不錯的地方,資料也很詳細~ [dart-cheat-sheet](https://github.com/Temidtech/dart-cheat-sheet) [Flutter-Cheat-Sheet](https://github.com/Temidtech/Flutter-Cheat-Sheet) ## 在線編寫和運行 Dart https://dartpad.dartlang.org/ https://dartpad.cn/ # Dart Libraries 和 第三方包管理 首先我們需要知道,Dart 是依賴于庫的,從而實現相應的功能; | 庫名 | 作用 | | --- | --- | | `dart:core` | 內置類型,集合和其他核心功能。**每個Dart程序默認會自動導入該庫** | | `dart:async` | 異步編程通常使用回調函數,但Dart提供了備選方案:[Future](https://api.dartlang.org/stable/dart-async/Future-class.html) 和 [Stream](https://api.dartlang.org/stable/dart-async/Stream-class.html) 對象。未來就像是對將來某個時候提供結果的承諾。 Stream是一種獲取值序列的方法,例如事件。 Future,Stream等等都在 dart:async 庫([API參考](https://api.dartlang.org/stable/dart-async/dart-async-library.html))中。 | | `dart:math` | `dart:math` 庫(API參考)提供常見功能, 如正弦和余弦,最大值和最小值,以及常量,如pi 和 e。 Math庫中的大多數功能都是作為頂級函數實現的。 | | `dart:convert` | `dart:convert` 庫(API參考)具有JSON和UTF-8轉換器,并支持創建其他轉換器。 [JSON](https://www.json.org/) 是一種用于表示結構化對象和集合的簡單文本格式。 [UTF-8](https://en.wikipedia.org/wiki/UTF-8) 是一種常見的可變寬度編碼,可以表示Unicode字符集中的每個字符。 | 當然還有其他的針對特定平臺的包,如:[dart:io](https://www.dartlang.org/dart-vm/io-library-tour) 、[dart:html](https://webdev.dartlang.org/guides/html-library-tour) 等,你可以在這里查看[所有包的api](https://api.dartlang.org/stable)。 Flutter 包的 api:https://docs.flutter.io/ 第三方包搜索:https://pub.dartlang.org/ ## 庫和可見性 `import` 和 `library`指令可以幫助您創建模塊化和可共享的代碼庫。庫不僅提供api,而且包含隱私部分:以下劃線(`_`)開頭的標識符僅在庫中可見。**每個Dart應用程序都是一個庫**,即使它不使用`library`指令。 可以使用包來分發庫。[pub](https://www.dartlang.org/tools/pub) 是SDK中包含的**包管理器**。 ## 使用庫 導入的唯一必需參數是指定庫的URI。對于內置庫,URI具有特殊的`dart:` 格式(scheme)。對于其他庫,您可以使用文件系統路徑或 `package:` 格式。 `package:` 格式指定由包管理器(如 pub 工具)提供的庫。例如: ```dart import 'package:meta/meta.dart'; ``` ## 指定庫前綴 通過 `as` 來制定庫前綴, ``` // lib1,和lib2 都有 Element 怎么辦? import 'package:lib1/lib1.dart'; import 'package:lib2/lib2.dart' as lib2; // 來自lib1的 Element Element element1 = Element(); // 來自lib2 的 Element lib2.Element element2 = lib2.Element(); ``` ### 使用庫中部分內容 ``` // 只導入 foo。 import 'package:lib1/lib1.dart' show foo; // 導入所有名稱,除了foo。 import 'package:lib2/lib2.dart' hide foo; ``` ## 懶加載一個庫 要延遲加載庫,首先必須使用 `deferred as` 導入庫。 您可以在一個庫上多次調用`loadLibrary()`,而不會出現任何問題。該庫只加載一次。 ```dart import 'package:greetings/hello.dart' deferred as hello; Future greet() async { // 通過await ,暫停等待庫的加載。有關async和await的詳細信息,請參閱[異步支持](https://www.dartlang.org/guides/language/language-tour#asynchrony-support) await hello.loadLibrary(); hello.printGreeting(); } ``` ## 創建自己的庫程序包 你可以[創建自己的庫](https://www.dartlang.org/guides/libraries/create-library-packages)。 如何組織庫源代碼。 如何時使用 `export` 指令。 何時使用 `part` 指令。 [其他常用庫](https://www.dartlang.org/guides/libraries/useful-libraries) # [基礎語法](https://www.dartlang.org/guides/language/language-tour) ## [關鍵字](https://www.dartlang.org/guides/language/language-tour#keywords) ![](https://box.kancloud.cn/e92dfaafda7899d97c18b6db64be0a75_556x496.png) 帶有字樣1的是內置標志符號,帶有2字樣的是Dart2新增的用于支持異步的關鍵字,其他的都是保留字! ## 語法規則 * 通過 `var` 聲明變量而不指定類型; * Dart 是強類型語言,但是聲明變量時也可以不指定類型,因為**Dart 可以自動推斷**, ``` var number = 16; ``` 在上面的例子中,變量number 就被自動推斷為`int` 類型 * 如果對象不限于單個類型,請[按照設計準則](https://www.dartlang.org/guides/language/effective-dart/design#do-annotate-with-object-instead-of-dynamic-to-indicate-any-object-is-allowed)指定 `Object` 或者 `dynamic` 類型。 ``` dynamic name = 'Bob'; ``` * Dart中所有的變量包括數字、函數和`null` 都是對象,每一個 對象都是一個類的實例,他們都繼承于 `Object`。 * Dart 支持泛型,如`List<int>`表示集合元素類型為整型、`List<dynamic>` 表示元素類型為任何類型 * Dart 除了支持我們常見的靜態函數(類直接調用)和普通函數(對象調用)外,同時也支持頂級函數如`main()` 和嵌套函數(函數里面的函數,也叫本地函數) * 與函數類似,Dart 也支持頂級變量,同時支持靜態變量和實例變量,實例變量也被叫做字段或屬性 * 和 java 不同,Dart 沒有 `public`、`protected`、`private`權限修飾符,在 Dart 里面的以下劃線`_`開頭的標志符表示是私有的 * Dart 里面的標志符號由`_`、字母和 數字組成,只能以`_`或者字母開頭 * 要注意區分表達式和語句的不同,如`var a = 3 + 2`;整體是一個賦值語句,`=` 右邊部分即 `3 + 2` 是一個表達式 * Dart 工具會向你發出兩種類型的提醒:警告和錯誤。警告代表你的代碼可能有問題,但是不會阻止程序的運行;**錯誤分為編譯錯誤和運行錯誤**,前者會阻止程序的運行,后者則會在程序運行時拋出異常! ## Final 和 Const 在 Dart 中,未初始化的變量擁有一個默認的初始化值:`null`。即便數字也是如此,因為在 Dart 中一切皆為對象,數字也不例外。 `const` 表示編譯時常量,即在代碼還沒有運行時我們就知道它聲明變量的值是什么; `final` 不僅有 `const` 的編譯時常量的特性,最重要的它是運行時常量,并且 `final` 是惰性初始化,即在運行時第一次使用前才初始化 ```dart const int a = 1; final int a = 8; const b = false; const c = a; const d = 5 * 3; final x = new DateTime.now(); // 正確 const x = new DateTime.now(); // 錯誤 final y = sin(90); // 正確 const y = sin(90); // 錯誤 ``` ## 內置類型 ### Numbers 1. `int` 整數值不大于64位,具體取決于平臺。 2. `double` 64位(雙精度)浮點數,由IEEE754標準指定。 **`int` 和 `double` 都是 `num` 的子類型** 示例: ``` int x = 1; int hex = 0xDEADBEEF; double y = 1.1; double exponents = 1.42e5; ``` ### Booleans Dart是強布爾類型檢查,只有當值是 `true` 是才為真,其他都是 `false`,聲明時用 `bool` ### Strings ``` //拼接字符串 var s5 = 'dd''ff' "ee"; //上面的方法等價于 var s6 = 'dd' + 'ff' + "ee"; // 多行文本使用方法,三單引號 或者 雙引號 var s1 = ''' You can create multi-line strings like this one. '''; var s2 = """This is also a multi-line string."""; // 通過 在前面添加 r 來表示原生字符串,原本輸出,不會解釋變量和轉義字符。 var s = r'In a raw string, not even \n gets special treatment $height.'; ``` ### Lists 在 Dart 語言中,具有一系列相同類型的數據被稱為 List 對象。 Dart List 對象類似JavaScript 語言的 array 對象。 ```dart var list = [1, 2, 3]; //分析器自動推斷list為List<int>,所以里面不能加入其他類型的元素 print(list.length); //3 list[1] = 11; print(list.toString()); //[1, 11, 3] var constantList = const [1, 2, 3]; // constantList[1] = 1; //因為前面的賦值使用了const 所以這句會報錯. constantList= [5]; //這樣可以 ``` ### Maps map 是一個包含 `key` 和 `value` 的對象,`key` 不能重復 ``` var gifts = { // Key: Value 'first': 'partridge', 'second': 'turtledoves', 'fifth': 'golden rings' }; var nobleGases = { 2: 'helium', 10: 'neon', 18: 'argon', }; var gifts2 = new Map(); gifts['first'] = 'partridge'; gifts['second'] = 'turtledoves'; gifts['fifth'] = 'golden rings'; var nobleGases2 = new Map(); nobleGases[2] = 'helium'; nobleGases[10] = 'neon'; nobleGases[18] = 'argon'; //獲取value print(gifts2['first']);// partridge; print(gifts2.length);// 3 ``` ### runes Dart 中 使用 `runes` 來獲取UTF-32字符集的字符。String的 `codeUnitAt` 和 `codeUnit` 屬性可以獲取UTF-16字符集的字符 ```dart var clapping = '\u{1f44f}'; print(clapping); print(clapping.codeUnits); print(clapping.runes.toList()); Runes input = new Runes( '\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}'); print(new String.fromCharCodes(input)); ``` ### symbols symbol 字面量是編譯時常量,在標識符前面加`#`。如果是動態確定,則使用`Symbol` 構造函數,通過`new`來實例化.你可能永遠也用不到 `Symbol ` ``` print(#s == new Symbol('s'));//true ``` # 函數 ```dart bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null; //箭頭函數,`=>` 實際為 `{ return expr; }` // 可選命名參數 /// Sets the [bold] and [hidden] flags ... void enableFlags({bool bold, bool hidden}) {...} // 可選位置參數 String say(String from, String msg, [String device]) { var result = '$from says $msg'; if (device != null) { result = '$result with a $device'; } return result; } say('Bob', 'Howdy') ; ``` ## 頂級函數 以下是測試頂級函數,靜態方法和實例方法的示例: ```dart void foo() {} // 頂級函數 A top-level function class A { static void bar() {} // A static method void baz() {} // An instance method } void main() { var x; // Comparing top-level functions. x = foo; assert(foo == x); // Comparing static methods. x = A.bar; assert(A.bar == x); // Comparing instance methods. var v = A(); // Instance #1 of A var w = A(); // Instance #2 of A var y = w; x = w.baz; // These closures refer to the same instance (#2), // so they're equal. assert(y.baz == x); // These closures refer to different instances, // so they're unequal. assert(v.baz != w.baz); } ``` ## 可選參數 * 名稱可選參數,調用一個函數時,你可以指定參數名稱,語法 `paramName: value`。 舉例: ```dart enableFlags(bold: true, hidden: false); ``` 那如何定義這樣的函數呢?使用 `{param1, param2, …}`來指定名稱參數: ```dart /// Sets the [bold] and [hidden] flags ... void enableFlags({bool bold, bool hidden = false}) {...} ``` **Flutter** 中實例創建表達式很復雜,所以 widget 構造時使用名稱可選參數。這使得 實例創建表達式 更易讀。 你可以使用`@required`注解來標注名稱參數,在任何 dart 代碼中,這表示這是一個 必填的參數。 舉例: ```dart const Scrollbar({Key key, @required Widget child}) ``` 當一個`Scrollbar`被構建的時候,如果缺失 `child`字段,語法會報錯。 `Required`定義在 [meta](https://pub.dev/packages/meta) 包中。可以直接導入 `package:meta/meta.dart`,也可以導入其他包來暴露 `meta`, 比方說 `package:flutter/material.dart`。 * 可選的位置參數,用`[]`它們標記為可選的位置參數: ```dart String say(String from, String msg, [String device]) { var result = '$from says $msg'; if (device != null) { result = '$result with a $device'; } return result; } say('Bob', 'Howdy'); // 不帶可選參數調用,結果是: Bob says Howdy say('Bob', 'Howdy', 'smoke signal'); //結果是:Bob says Howdy with a smoke signal ``` ## 參數默認值 下面的示例定義了一個函數 `doStuff()`,它為 `list` 參數指定了默認列表,為 `gifts` 參數指定了默認映射。 ```dart void doStuff( {List<int> list = const [1, 2, 3], Map<String, String> gifts = const { 'first': 'paper', 'second': 'cotton', 'third': 'leather' }}) { print('list: $list'); print('gifts: $gifts'); } ``` ## `main` 函數 每一個程序都要有一個主函數,它是 `app` 的入口,無返回值,有一個 `List<String>`類型的可選參數。 下面是一個web app的主函數: ``` void main() { querySelector('#sample_text_id')//獲取頁面上的button對象 ..text = 'Click me!'//設置文本 ..onClick.listen(reverseText);//設置監聽 } ``` 注:`..`是一種級聯操作符,它返回調用者本身,這樣就可以連續調用同一個對象上的多個方法,實現鏈式操作! 下面是一個帶參的主函數,需要命令行操作: ``` //運行程序:dart args.dart 1 test //args.dart 是程序文件名 1 test 是參數 void main(List<String> arguments) { print(arguments.length);//2 print(int.parse(arguments[0]));//1 print(arguments[1]);//test } ``` ## 函數對象 * 函數可以作為一個參數 ```dart void printElement(int element) { print(element); } var list = [1, 2, 3]; // Pass printElement as a parameter. list.forEach(printElement);// 1 2 3 ``` * 函數可以賦值給一個變量 ```dart var loudify = (msg) => '!!! ${msg.toUpperCase()} !!!'; print(loudify('hello'));//!!! HELLO !!! ``` 上面用到了匿名函數,下面的將會介紹。 ## 匿名函數 大多數函數都有名字,如 `main()`,沒有名字的函數被稱為匿名函數,有時也叫做`閉包`或 `lambda ` ``` var list = ['apples', 'bananas', 'oranges']; list.forEach((item) { print('${list.indexOf(item)}: $item'); }); // 上面的函數可以改寫為箭頭函數 list.forEach( (item) => print('${list.indexOf(item)}: $item')); // 0: apples 1: bananas 2: oranges ``` ## 作用域 ``` bool topLevel = true; void main() { var insideMain = true; void myFunction() { var insideFunction = true; void nestedFunction() { // 該函數可以訪問外部所有變量 var insideNestedFunction = true; assert(topLevel); assert(insideMain); assert(insideFunction); assert(insideNestedFunction); } } } ``` ## 詞法閉包 ```dart /// Returns a function that adds [addBy] to the /// function's argument. Function makeAdder(num addBy) { return (num i) => addBy + i; // 返回一個函數, addBy會被記得 } void main() { // Create a function that adds 2. var add2 = makeAdder(2); // Create a function that adds 4. var add4 = makeAdder(4); assert(add2(3) == 5); assert(add4(3) == 7); } ``` ## 函數返回值 函數沒有明確返回值時,`return null` 會被隱式添加。 ``` foo() {} ``` # 運算符 ## `==` 如果 x 或 y 為 `null` ,如果兩者都為`null` 返回`true`,如果只有一個為`null` 返回`false`。 判斷兩個對象完全相同,使用 [`identical()`](https://api.dartlang.org/stable/dart-core/identical.html) ## 類型檢測運算符 `as`、`is`、`is!` 在運行時檢測類型。 ``` if (emp is Person) { // Type check emp.firstName = 'Bob'; } // 您可以使用 as 運算符縮短上面的代碼,如果 emp 是 null 或不是Person,as 檢測到錯誤會拋出異常 (emp as Person).firstName = 'Bob'; ``` ## `??`操作符 如果第一個表達式值不為 `null`,返回它的值,否則就返回第二個值; ``` //如果b為 null,則將值賦給 b;否則,b 保持不變 b ?? = value; String playerName(String name) => name ?? 'Guest'; // 等價于下面:Slightly longer version uses ?: operator. String playerName(String name) => name != null ? name : 'Guest'; ``` ## `..`級聯運算符(僅為特殊語法) * 級聯運算符`..`允許您對同一個對像進行一系列的操作。除了函數調用之外,還可以訪問同一對象上的字段。這通常會為您節省創建臨時變量的步驟,并允許您編寫更流暢的代碼。 ```dart querySelector('#confirm') // Get an object. ..text = 'Confirm' // Use its members. ..classes.add('important') ..onClick.listen((e) => window.alert('Confirmed!')); ``` * 上述例子相對于: ```dart var button = querySelector('#confirm'); button.text = 'Confirm'; button.classes.add('important'); button.onClick.listen((e) => window.alert('Confirmed!')); ``` * 級聯符號也可以嵌套使用。 例如: ```dart final addressBook = (AddressBookBuilder() ..name = 'jenny' ..email = 'jenny@example.com' ..phone = (PhoneNumberBuilder() ..number = '415-555-0100' ..label = 'home') .build()) .build(); ``` * 當返回值是void時不能構建級聯。 例如,以下代碼失敗: ```dart var sb = StringBuffer(); sb.write('foo') // 返回void ..write('bar'); // 這里會報錯 ``` **注意: 嚴格地說,級聯的..符號不是操作符。它只是Dart語法的一部分。** > https://www.jianshu.com/p/9e5f4c81cc7d ## 有條件的成員訪問符 ``` foo?.bar //當foo為null時,foo?.bar 為null ``` ## 流程控制語句 ``` if (isRaining()) { you.bringRainCoat(); } else if (isSnowing()) { //if else 語句 you.wearJacket(); } else { car.putTopDown(); } var callbacks = []; for (var i = 0; i < 2; i++) { //for 語句 callbacks.add(() => print(i)); } callbacks.forEach((c) => c()); //forEach 語句 var collection = [0, 1, 2]; for (var x in collection) { //for in 語句 print(x); // 0 1 2 } for (int i = 0; i < candidates.length; i++) { var candidate = candidates[i]; if (candidate.yearsExperience < 5) { continue; //跳入下一次循環 } candidate.interview(); } var command = 'CLOSED'; switch (command) { case 'CLOSED': executeClosed(); continue nowClosed; // 繼續在nowClosed標簽上執行。 nowClosed: case 'NOW_CLOSED': //CLOSED 和 NOW_CLOSED都會執行該語句 executeNowClosed(); break; } ``` ## 斷言 第一個參數,可以是任何返回bool值的表達式,第二個參數,是顯示的信息。 成功繼續執行,如果為false,則斷言失敗并拋出異常([AssertionError](https://api.dartlang.org/stable/dart-core/AssertionError-class.html))。 ``` assert(urlString.startsWith('https'), 'URL ($urlString) should start with "https".'); ``` ## 異常 ``` throw 'Out of llamas!'; //拋出任何形式的異常。 try { breedMoreLlamas(); } on OutOfLlamasException { // A specific exception buyMoreLlamas(); } on Exception catch (e) { print('Exception details:\n $e'); } catch (e, s) { //第一個是拋出的異常,第二個是堆棧跟蹤( StackTrace 對象 )。 print('Exception details:\n $e'); print('Stack trace:\n $s'); } finally { // 無論是否拋出異常,確保某些代碼總能夠運行,請使用 finally子句 cleanLlamaStalls(); // Then clean up. } ``` 要部分處理異常,同時不停止程序的執行,請使用 `rethrow` 關鍵字。 ``` void misbehave() { try { dynamic foo = true; print(foo++); // Runtime error } catch (e) { print('misbehave() partially handled ${e.runtimeType}.'); rethrow; // Allow callers to see the exception. } } void main() { try { misbehave(); } catch (e) { print('main() finished handling ${e.runtimeType}.'); } } ``` # Class ## 常量構造函數 ```dart // 常量上下文,const 為可選 const pointAndLine = { 'point': [ImmutablePoint(0, 0)], 'line': [ImmutablePoint(1, 10), ImmutablePoint(-2, 11)], }; var a = const ImmutablePoint(1, 1); // Creates a constant var b = ImmutablePoint(1, 1); // 此時沒有const 修飾,又不在常量上下文中 assert(!identical(a, b)); // NOT the same instance! ``` ## 對象運行時類型 `runtimeType`,該屬性返回一個[Type](https://api.dartlang.org/stable/dart-core/Type-class.html) 對象 ``` print('The type of a is ${a.runtimeType}'); ``` ## 構造函數 **子類不會從其父類繼承構造函數,但自身也會有默認構造函數**。默認構造函數沒有參數,并在超類中調用無參數構造函數。 ``` class Point { num x, y; //在構造函數體運行之前, 用于設置x和y的語法糖 Point(this.x,this.y); } ``` ## 調用父類命名構造函數 ``` class Person { String firstName; final num x; final num y; final num distanceFromOrigin; Person.fromJson(Map data) { print('in Person'); } // 初始化那三個 final 字段 Point(x, y) : x = x, y = y, distanceFromOrigin = sqrt(x * x + y * y); // Delegates to the main constructor. Point.alongXAxis(num x) : this(x, 0); } class Employee extends Person { // Person沒有默認構造函數;調用父類命名構造函數。 Employee.fromJson(Map data) : super.fromJson(data) { print('in Employee'); } } main() { var emp = new Employee.fromJson({}); // Prints: // in Person // in Employee } // ============ class ImmutablePoint { static final ImmutablePoint origin = const ImmutablePoint(0, 0); final num x, y; // 常量構造函數 const ImmutablePoint(this.x, this.y); } // ============ class Logger { final String name; bool mute = false; // _cache is library-private, thanks to // the _ in front of its name. static final Map<String, Logger> _cache = <String, Logger>{}; //關鍵字 `factory` 自定義構造函數邏輯,但是無法訪問 this factory Logger(String name) { if (_cache.containsKey(name)) { return _cache[name]; } else { final logger = Logger._internal(name); _cache[name] = logger; return logger; } } Logger._internal(this.name); void log(String msg) { if (!mute) print(msg); } } ``` ## getter 和 setter ``` class Rectangle { num left, top, width, height; Rectangle(this.left, this.top, this.width, this.height); // 定義兩個計算屬性:right 和 bottom。 num get right => left + width; set right(num value) => left = value - width; num get bottom => top + height; set bottom(num value) => top = value - height; } void main() { var rect = Rectangle(3, 4, 20, 15); assert(rect.left == 3); rect.right = 12; assert(rect.left == -8); } ``` ## 抽象方法 `abstract`修飾符 ``` abstract class Doer { // 定義實例變量和方法...... //... void doSomething(); // 定義了一個抽象方法,所以類必須為抽象類 } class EffectiveDoer extends Doer { void doSomething() { // 這里繼承并實現對應的抽象方法 } } ``` ## `implements` 一個類實現多個接口: ``` // 一個 person 類, 隱式接口包含 greet(). class Person { // In the interface, but visible only in this library. final _name; // Not in the interface, since this is a constructor. Person(this._name); // In the interface. String greet(String who) => 'Hello, $who. I am $_name.'; } // Person接口的實現。 class Impostor implements Person { get _name => ''; String greet(String who) => 'Hi $who. Do you know who I am?'; } String greetBob(Person person) => person.greet('Bob'); void main() { print(greetBob(Person('Kathy'))); print(greetBob(Impostor())); } ``` ## `extends` 可以在子類中通過 `super`,引用父類。 ``` class Television { void turnOn() { _illuminateDisplay(); } // ··· } class SmartTelevision extends Television { void turnOn() { super.turnOn(); _bootNetworkInterface(); } // ··· } ``` ## `@override` 對于所有 Dart 代碼有兩種可用注解:`@deprecated`和`@override`。 使用 `@override` 注解(annotation) 表明要覆蓋的成員。 ``` class SmartTelevision extends Television { @override void turnOn() {...} // ··· } ``` > [元數據](https://www.dartcn.com/guides/language/language-tour#%E5%85%83%E6%95%B0%E6%8D%AE) ## [covariant](https://www.dartlang.org/guides/language/sound-problems#the-covariant-keyword) 在類型安全的代碼中,縮小方法參數或實例變量的類型,可以使用 `covariant` (協變) 關鍵字 ``` class Animal { void chase(Animal x) { ... } //這里是父類型 } class Mouse extends Animal { ... } class Cat extends Animal { void chase(covariant Mouse x) { ... } //通過用子類型覆蓋參數的類型來收緊類型 } ``` ## 可重寫運算符 ``` class Vector { final int x, y; Vector(this.x, this.y); Vector operator +(Vector v) => Vector(x + v.x, y + v.y); Vector operator -(Vector v) => Vector(x - v.x, y - v.y); // Operator == and hashCode not shown. For details, see note below. // ··· } void main() { final v = Vector(2, 3); final w = Vector(2, 2); assert(v + w == Vector(4, 5)); assert(v - w == Vector(0, 1)); } ``` ## noSuchMethod() ``` class A { // 除非你覆蓋noSuchMethod,否則使用 不存在的成員導致 NoSuchMethodError。 @override void noSuchMethod(Invocation invocation) { print('You tried to use a non-existent member: ' + '${invocation.memberName}'); } } ``` ## 枚舉類型 枚舉類型(通常稱為enumerations 或者 enums)是一種特殊類,用于表示固定數量的常量值。 使用 `enum` 關鍵字聲明枚舉類型: ``` enum Color { red, green, blue } // Color.red.index == 0,index 從0 開始 List<Color> colors = Color.values; // 通過values 獲取所有枚舉值 assert(colors[2] == Color.blue); ``` ## mixins Mixins 是一種在多個類層次結構中 復用類代碼的方法。 ``` // 要實現一個 mixin,創建一個擴展 Object 的類,沒有構造函數,并且沒有調用 super mixin Musical { bool canPlayPiano = false; bool canCompose = false; bool canConduct = false; void entertainMe() { if (canPlayPiano) { print('Playing piano'); } else if (canConduct) { print('Waving hands'); } else { print('Humming to self'); } } } // 通過 with 關鍵字 使用 mixins class Maestro extends Person with Musical, Aggressive, Demented { Maestro(String maestroName) { name = maestroName; canConduct = true; } } ``` > [為類添加功能:Mixin](https://www.dartcn.com/guides/language/language-tour#%E4%B8%BA%E7%B1%BB%E6%B7%BB%E5%8A%A0%E5%8A%9F%E8%83%BD-mixin) ## static 對于常見或廣泛使用的實用程序和功能,請考慮使用 **頂級函數** 而不是 靜態方法。 您可以使用靜態方法作為編譯時常量。例如,您**可以將靜態方法作為參數傳遞給常量構造函數**。 ``` import 'dart:math'; class Point { static const initialCapacity = 16; num x, y; Point(this.x, this.y); static num distanceBetween(Point a, Point b) { var dx = a.x - b.x; var dy = a.y - b.y; return sqrt(dx * dx + dy * dy); } } void main() { var a = Point(2, 2); var b = Point(4, 4); var distance = Point.distanceBetween(a, b); //只能類調用,不能通過實例調用 assert(Queue.initialCapacity == 16); assert(2.8 < distance && distance < 2.9); print(distance); } ``` # 泛型 Generics 如果查看基本數組類型的API文檔 [`List`](https://api.dartlang.org/stable/dart-core/List-class.html),您會看到該類型實際上是List <E>。 <...> 符號 將 List 標記為 generic (或 parameterized 參數化)類型 - 具有形式類型參數的類型。按照慣例,類型變量具有單字母名稱,例如 E,T,S,K 和 V。 ```js // 集合字面量 var names = <String>['Seth', 'Kathy', 'Lars']; var pages = <String, String>{ 'index.html': 'Homepage', 'robots.txt': 'Hints for web robots', 'humans.txt': 'We are people, not machines' }; // 泛型構造函數 var views = Map<int, View>(); //檢測運行時 具體類型信息 var names = List<String>(); names.addAll(['Seth', 'Kathy', 'Lars']); print(names is List<String>); // true 檢測具體類型信息 ``` ## 限制泛型 通過 `extends` 關鍵字 限制 泛型 ```js // 通過 extends 關鍵字 限制 泛型 class Foo<T extends SomeBaseClass> { // Implementation goes here... String toString() => "Instance of 'Foo<$T>'"; } class Extender extends SomeBaseClass {...} // 可以SomeBaseClass或其任何子類作為泛型參數: var someBaseClassFoo = Foo<SomeBaseClass>(); var extenderFoo = Foo<Extender>(); // 也可以不指定泛型參數: var foo = Foo(); print(foo); // Instance of 'Foo<SomeBaseClass>' // 其他情況會導致錯誤 var foo = Foo<Object>(); ``` ### 泛型方法 最初Dart 只能限制 class;最新語法,通過泛型方法,對函數、方法使用類型參數。 1. 在函數的返回中返回類型(T) 2. 在參數的類型中使用(List<T>) 3. 在局部變量的類型中(T tmp) ```dart T first<T>(List<T> ts) { // 做一些初步工作或錯誤檢查,然后...... T tmp = ts[0]; // 做一些額外的檢查或處理...... return tmp; } ``` # 異步支持 Dart庫中包含許多返回 [Future](https://api.dartlang.org/stable/dart-async/Future-class.html) 或 [Stream](https://api.dartlang.org/stable/dart-async/Stream-class.html) 對象的函數。這些函數是異步的:它們在進行可能耗時的操作(例如I / O)后返回,而不等待該操作完成。 `async` 和 `await` ,讓我們可以編寫類似同步的代碼。 ## 處理 Futures 1. 使用 `async`和 `await`。` await expression` 的 `expression` 通常會被包裹為一個 `Future` 類型。 2. 使用Future API,如[庫瀏覽中所述](https://www.dartlang.org/guides/libraries/library-tour#future)。 ```dart // await 需要的 定義為 async 的異步方法中,返回一個 Future 對象 Future checkVersion() async { try { version = await lookUpVersion(); // Do something with version } catch (e) { // 可以使用 try catch 進行相應處理 } } // main 函數 定義為一個異步函數 Future main() async { checkVersion(); print('In main: version is ${await lookUpVersion()}'); } ``` ## 異步函數 `Future<void>` 沒有有效的返回值時,可以這樣定義。 ``` Future<String> lookUpVersion() async => '1.0.0'; ``` ## 處理 Streams `await for` **不能對 UI事件監聽器 使用**,因為UI事件可能會持續不斷的存在。 1. 使用`async`和異步for循環(`await for`)。 2. 使用Stream API,如[庫瀏覽中所述](https://www.dartlang.org/guides/libraries/library-tour#stream)。 ```dart await for (varOrType identifier in expression) { // Executes each time the stream emits a value. } ``` `expression`的值必須具有 Stream 類型。執行過程如下: 1. 等待直到流發出一個值。 2. 執行for 循環的主體,將變量設置為該發出的值。 3. 重復1 和 2,直到關閉流。 要停止偵聽流,**可以使用 `break` 或 `return`語句**,該語句會從for循環中斷開 并從流中取消訂閱。 要在 `main()` 函數中使用異步for循環,`main()` 的主體必須標記為 ·async·: ```dart Future main() async { // ... await for (var request in requestServer) { handleRequest(request); } // ... } ``` ## 生成器函數 當您需要延遲地生成一個值序列時,請考慮使用生成器函數。Dart內置支持兩種生成器函數: * **同步生成器**:返回 [Iterable](https://api.dartlang.org/stable/dart-core/Iterable-class.html) 對象 * **異步生成器**:返回 [Stream](https://api.dartlang.org/stable/dart-async/Stream-class.html) 對象 要實現同步生成器函數,將函數體標記為 `sync*`,并使用 `yield` 語句傳遞值: ```dart Iterable<int> naturalsTo(int n) sync* { int k = 0; while (k < n) yield k++; } ``` 要實現異步生成器函數,將函數體標記為 `async*`,并使用 `yield` 語句傳遞值: ```js Stream<int> asynchronousNaturalsTo(int n) async* { int k = 0; while (k < n) yield k++; } ``` 如果您的生成器是遞歸的,您可以使用 `yield*` 來改進它的性能: ```js Iterable<int> naturalsDownFrom(int n) sync* { if (n > 0) { yield n; yield* naturalsDownFrom(n - 1); //遞歸調用 } } ``` 有關生成器的更多信息,請參閱文章 [Dart語言異步支持:Phase 2](https://www.dartlang.org/articles/language/beyond-async)。 ## 可調用的類 實現 `call()`方法可以讓你的Dart 類像函數一樣被調用。 ```js // WannabeFunction 類定義了一個 `call()` 函數 class WannabeFunction { call(String a, String b, String c) => '$a $b $c!'; } main() { var wf = new WannabeFunction(); var out = wf("Hi", "there,", "gang"); // 類像函數一樣被調用。 print('$out'); } ///執行結果 Hi there, gang! ``` 有關類的更多信息,請參見[Dart中的模擬函數](https://www.dartlang.org/articles/language/emulating-functions)。 # 隔離器 大多數計算機,甚至在移動平臺上,都有多核cpu。為了利用所有這些核心,開發人員通常使用同時運行的共享內存線程。但是,共享狀態并發容易出錯并且可能增加代碼的復雜度。 不同于線程,所有Dart代碼都運行在隔離器內部,而不是線程。每個隔離都有它自己的內存堆,確保任何其他隔離器都不能訪問隔離狀態。 有關更多信息,請參見 [dart:isolate庫文檔](https://api.dartlang.org/stable/dart-isolate) 。 ## 類型定義 在 Dart 中,函數是對象,就像字符串和數字是對象一樣。`typedef`或 `function-type`為函數提供一個類型別名,你可以在聲明字段和返回類型時使用這個名稱。當函數類型被分配給變量時,`typedef` 保留類型信息。 ```js typedef Compare = int Function(Object a, Object b); class SortedCollection { Compare compare; SortedCollection(this.compare); } // Initial, broken implementation. int sort(Object a, Object b) => 0; void main() { SortedCollection coll = SortedCollection(sort); assert(coll.compare is Function); assert(coll.compare is Compare); } ``` *注意:目前,`typedefs` 僅限于函數類型。我們期望這種情況會改變。 * 因為 `typedef` 僅僅是別名,所以它們提供了一種檢查任何函數類型的方法。例如: ``` typedef Compare<T> = int Function(T a, T b); int sort(int a, int b) => a - b; void main() { assert(sort is Compare<int>); // True! } ``` # 元數據 (Metadata ) `@deprecated` 和 `@override` 只有這兩個注解在所有Dart 代碼中,都是可用的。 ``` class Television { /// _Deprecated:改用 [turnOn] ._ @deprecated void activate() { turnOn(); } /// Turns the TV's power on. void turnOn() {...} } ``` ## 自定義元數據注解 元數據可以出現在library、class、typedef、類型參數、構造函數、factory、函數、字段、參數或變量聲明之前,也可以出現在 `import` 或 `export`指令之前。您可以使用反射在運行時 檢索元數據。 ``` js // 通過 `library` 指令 表明 todo庫 library todo; class Todo { final String who; final String what; const Todo(this.who, this.what); } // 使用 `@todo` 注解: import 'todo.dart'; @Todo('seth', 'make this do something') void doSomething() { print('do something'); } ``` # 注釋 * 單行注釋 以 `//` 開頭 ``` void main() { // TODO: refactor into an AbstractLlamaGreetingFactory? print('Welcome to my Llama farm!'); } ``` * 多行注釋 以 `/*` 開頭 ``` void main() { /* * This is a lot of work. Consider raising chickens. Llama larry = Llama(); larry.feed(); larry.exercise(); larry.clean(); */ } ``` **文檔注釋**是以`///`或`/**`開頭的多行或單行注釋。在連續行上使用///與多行文檔注釋具有相同的效果。 Dart編譯器會忽略所有文本,除非它被括在括號中。使用括號,您可以引用類、方法、字段、頂級變量、函數和參數。括號中的名稱在文檔化程序元素的詞法范圍內解析。 ```dart /// A domesticated South American camelid (Lama glama). /// /// Andean cultures have used llamas as meat and pack /// animals since pre-Hispanic times. class Llama { String name; /// Feeds your llama [Food]. /// /// The typical llama eats one bale of hay per week. void feed(Food food) { // ... } /// Exercises your llama with an [activity] for /// [timeLimit] minutes. void exercise(Activity activity, int timeLimit) { // ... } } ``` 在生成的文檔中,`[Food]` 成為了與Food類的API文檔的鏈接。 解析Dart代碼并生成HTML文檔,可以使用 [SDK的文檔生成工具](https://github.com/dart-lang/dartdoc#dartdoc) 。 有關生成文檔的示例,請參閱 [Dart API文檔](https://api.dartlang.org/stable) 。 有關如何構造注釋的建議,請參閱 [Dart文檔注釋的指南](https://www.dartlang.org/guides/language/effective-dart/documentation) 。 # 結束 本頁概述了Dart語言中常用的功能。正在實施更多功能,但我們希望它們不會破壞現有代碼。有關更多信息,請參閱[Dart語言規范](https://www.dartlang.org/guides/language/spec)和 [有效Dart](https://www.dartlang.org/guides/language/effective-dart)。 # 示例 ```dart import 'dart:math'; abstract class Shape { num get area; } class Circle implements Shape { final num radius; //Circle(this.radius); num get area => pi * pow(radius, 2); } class Square implements Shape { final num side; Square(this.side); num get area => pow(side, 2); } main() { final circle = Circle(2); final square = Square(2); print(circle.area); print(square.area); } //============================= import 'dart:math'; class Rectangle { int width; int height; Point origin; Rectangle({this.origin = const Point(0, 0), this.width = 0, this.height = 0}); @override String toString() => 'Origin: (${origin.x}, ${origin.y}), width: $width, height: $height'; } main() { print(Rectangle(origin: const Point(10, 20), width: 100, height: 200)); print(Rectangle(origin: const Point(10, 10))); print(Rectangle(width: 200)); print(Rectangle()); } class Bicycle { int cadence; int _speed = 0; //設置 只讀變量 int get speed => _speed; //int get speed => _speed int gear; Bicycle(this.cadence, this.gear); //構造函數 // change 這 speed variable void applyBrake(int decrement) { _speed -= decrement; } void speedUp(int increment) { _speed += increment; } // 重寫默認方法 @override String toString() => 'Bicycle: $_speed mph'; //帶名字類似ES6中的胖箭頭函數寫法 } // 主入口方法 void main() { var bike = Bicycle(2, 1); //可以缺少 new bike.applyBrake(1); //調用方法 print(bike); } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看