<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之旅 廣告
                本教程展示了如何使用下列庫的主要功能,這些庫包含在所有Dart平臺中: [TOC] [dart:core](#) 內置類型、集合和其他核心功能。這個庫被自動導入到每個Dart程序中。 [dart:async](#) 支持異步編程,使用諸如Future和Stream之類的類。 [dart:math](#) 數學常數和函數,和隨機數發生器。 [dart:convert](#) 用于在不同數據表示之間轉換的編碼器和解碼器,包括JSON和UTF-8。 這個頁面只是一個概述;它只覆蓋了幾個dart:*庫,沒有第三方庫。特定于平臺的dart:io和dart:html庫都包含在dart:io tour和dart:html tour中。 其他可以找到庫信息的地方是[pub.darlang.org](https://pub.dartlang.org/)和[Dart web developer library guide](https://webdev.dartlang.org/guides/web-programming)。您可以在dart API引用中找到所有dart:* [庫的API文檔](https://api.dartlang.org/stable),如果您正在使用Flutter,則可以找到[Flutter API文檔](https://docs.flutter.io/)。 >DartPad提示:你可以把本頁的代碼復制到[DartPad](https://dartpad.dartlang.org/)上運行。 > # dart:core - numbers, collections, strings, 等 dart:core 庫 ([API文檔](https://api.dartlang.org/stable/dart-core/dart-core-library.html))提供了一組小型但關鍵的內置功能。這個庫被自動導入到每個Dart程序中。 ## 向控制臺打印 頂級print()方法接受單個參數(任何對象),并在控制臺中顯示該對象的字符串值(由toString()返回)。 ~~~ print(anObject); print('I drink $tea.'); ~~~ 有關基本字符串和toString()的更多信息,請參閱語言教程中的[Strings](https://www.dartlang.org/guides/language/language-tour#strings)。 ## Numbers dart:core庫定義了num、int和double類,它們有一些處理數字的基本工具。 您可以使用int和double的parse()方法將字符串轉換為整數或雙精度浮點數: ~~~ assert(int.parse('42') == 42); assert(int.parse('0x42') == 66); assert(double.parse('0.50') == 0.5); ~~~ 或者使用num的parse()方法,它在可能的情況下創建一個整數,否則創建一個double: ~~~ assert(num.parse('42') is int); assert(num.parse('0x42') is int); assert(num.parse('0.50') is double); ~~~ 要指定整數的基數,添加一個基數參數: ~~~ assert(int.parse('42', radix: 16) == 66); ~~~ 使用toString()方法將int或double轉換為字符串。要指定小數點右邊的位數,使用[toStringAsFixed()](https://api.dartlang.org/stable/dart-core/num/toStringAsFixed.html)。要指定字符串中的有效位數,使用[toStringAsPrecision()](https://api.dartlang.org/stable/dart-core/num/toStringAsPrecision.html): ~~~ // Convert an int to a string. assert(42.toString() == '42'); // Convert a double to a string. assert(123.456.toString() == '123.456'); // Specify the number of digits after the decimal. assert(123.456.toStringAsFixed(2) == '123.46'); // Specify the number of significant figures. assert(123.456.toStringAsPrecision(2) == '1.2e+2'); assert(double.parse('1.2e+2') == 120.0); ~~~ 有關更多信息,請參閱[int](https://api.dartlang.org/stable/dart-core/int-class.html)、[double](https://api.dartlang.org/stable/dart-core/double-class.html)和[num](https://api.dartlang.org/stable/dart-core/num-class.html)的API文檔。也可以看[dart:math](https://www.dartlang.org/guides/libraries/library-tour#dartmath---math-and-random)部分 ## 字符串和正則表達式 Dart中的字符串是UTF-16代碼單元的不可變序列。 本文檔的其他章節有關于字符串的更多信息。 您可以使用正則表達式(RegExp對象)在字符串中搜索并替換部分字符串。 String類定義了諸如split()、contains()、startsWith()、endsWith()等方法。 ### 在字符串中搜索 您可以在字符串中找到特定的位置,并檢查字符串是以特定模式開始還是以特定模式結束。例如: ~~~ // Check whether a string contains another string. assert('Never odd or even'.contains('odd')); // Does a string start with another string? assert('Never odd or even'.startsWith('Never')); // Does a string end with another string? assert('Never odd or even'.endsWith('even')); // Find the location of a string inside a string. assert('Never odd or even'.indexOf('odd') == 6); ~~~ ### 從字符串中提取數據 您可以分別從字符串中獲取字符串中的單個字符作為字符串或整數。 確切地說,您實際上獲得了單獨的UTF-16代碼單元; 諸如高音譜號符號('\ u {1D11E}')之類的高編號字符分別是兩個代碼單元。 您還可以提取子字符串或將字符串分割為一列子字符串: ~~~ // Grab a substring. assert('Never odd or even'.substring(6, 9) == 'odd'); // Split a string using a string pattern. var parts = 'structured web apps'.split(' '); assert(parts.length == 3); assert(parts[0] == 'structured'); // Get a UTF-16 code unit (as a string) by index. assert('Never odd or even'[0] == 'N'); // Use split() with an empty string parameter to get // a list of all characters (as Strings); good for // iterating. for (var char in 'hello'.split('')) { print(char); } // Get all the UTF-16 code units in the string. var codeUnitList = 'Never odd or even'.codeUnits.toList(); assert(codeUnitList[0] == 78); ~~~ ### 轉換為大寫或小寫 您可以輕松地將字符串轉換為其大寫和小寫變體: ~~~ // Convert to uppercase. assert('structured web apps'.toUpperCase() == 'STRUCTURED WEB APPS'); // Convert to lowercase. assert('STRUCTURED WEB APPS'.toLowerCase() == 'structured web apps'); ~~~ >注意:這些方法并不適用于所有語言。例如,土耳其字母表的dotless I被錯誤地轉換。 > ### 修剪和空字符串 使用trim()刪除所有前、后空白。要檢查字符串是否為空(長度為零),使用isEmpty。 ~~~ // Trim a string. assert(' hello '.trim() == 'hello'); // Check whether a string is empty. assert(''.isEmpty); // Strings with only white space are not empty. assert(' '.isNotEmpty); ~~~ ### 構建一個字符串 要以編程方式生成字符串,可以使用StringBuffer。在調用toString()之前,StringBuffer不會生成新的字符串對象。writeAll()方法有一個可選的第二個參數,它允許您指定分隔符(在本例中是空格)。 ~~~ var sb = StringBuffer(); sb ..write('Use a StringBuffer for ') ..writeAll(['efficient', 'string', 'creation'], ' ') ..write('.'); var fullString = sb.toString(); assert(fullString == 'Use a StringBuffer for efficient string creation.'); ~~~ ### 正則表達式 RegExp類提供了與JavaScript正則表達式相同的功能。使用正則表達式進行字符串的高效搜索和模式匹配。 ~~~ // Here's a regular expression for one or more digits. var numbers = RegExp(r'\d+'); var allCharacters = 'llamas live fifteen to twenty years'; var someDigits = 'llamas live 15 to 20 years'; // contains() can use a regular expression. assert(!allCharacters.contains(numbers)); assert(someDigits.contains(numbers)); // Replace every match with another string. var exedOut = someDigits.replaceAll(numbers, 'XX'); assert(exedOut == 'llamas live XX to XX years'); ~~~ 您也可以直接使用RegExp類。Match類提供對正則表達式匹配的訪問。 ~~~ var numbers = RegExp(r'\d+'); var someDigits = 'llamas live 15 to 20 years'; // Check whether the reg exp has a match in a string. assert(numbers.hasMatch(someDigits)); // Loop through all matches. for (var match in numbers.allMatches(someDigits)) { print(match.group(0)); // 15, then 20 } ~~~ ### 更多信息 有關字符串操作方法的完整列表,請參閱[字符串API文檔](https://api.dartlang.org/stable/dart-core/String-class.html)。還可以查看關于[StringBuffer](https://api.dartlang.org/stable/dart-core/StringBuffer-class.html)、[Pattern](https://api.dartlang.org/stable/dart-core/Pattern-class.html)、[RegExp](https://api.dartlang.org/stable/dart-core/RegExp-class.html)和[Match](https://api.dartlang.org/stable/dart-core/Match-class.html)的API文檔。 ## 集合(Collections) Dart帶有一個核心集合API,其中包括列表(list)、集合(sets)和映射(maps)的類。 ### Lists(列表) 正如本文檔list部分所示,您可以使用文字來創建和初始化列表。或者,使用列表構造函數之一。List類還定義了幾種向列表中添加項和從列表中刪除項的方法。 ~~~ // Use a List constructor. var vegetables = List(); // Or simply use a list literal. var fruits = ['apples', 'oranges']; // Add to a list. fruits.add('kiwis'); // Add multiple items to a list. fruits.addAll(['grapes', 'bananas']); // Get the list length. assert(fruits.length == 5); // Remove a single item. var appleIndex = fruits.indexOf('apples'); fruits.removeAt(appleIndex); assert(fruits.length == 4); // Remove all elements from a list. fruits.clear(); assert(fruits.length == 0); ~~~ 使用indexOf()查找列表中對象的索引: ~~~ var fruits = ['apples', 'oranges']; // Access a list item by index. assert(fruits[0] == 'apples'); // Find an item in a list. assert(fruits.indexOf('apples') == 0); ~~~ 使用sort()方法對列表進行排序。您可以提供一個比較兩個對象的排序函數。這個排序函數必須返回< 0表示較小,0表示相同,>0表示較大。下面的示例使用compareTo(),它由Comparable定義,由String實現。 ~~~ var fruits = ['bananas', 'apples', 'oranges']; // Sort a list. fruits.sort((a, b) => a.compareTo(b)); assert(fruits[0] == 'apples'); ~~~ 列表是參數化的類型,所以您可以指定列表應該包含的類型: ~~~ // This list should contain only strings. var fruits = List<String>(); fruits.add('apples'); var fruit = fruits[0]; assert(fruit is String); ~~~ 以下是錯誤示例: ~~~ fruits.add(5); // Error: 'int' can't be assigned to 'String' ~~~ 有關方法的完整列表,請參閱[List API文檔](https://api.dartlang.org/stable/dart-core/List-class.html)。 ### 集合(Sets) Dart中的集合是一組無序的獨特物品集合。因為集合是無序的,所以不能通過索引(位置)獲得集合的項。 ~~~ var ingredients = Set(); ingredients.addAll(['gold', 'titanium', 'xenon']); assert(ingredients.length == 3); // Adding a duplicate item has no effect. ingredients.add('gold'); assert(ingredients.length == 3); // Remove an item from a set. ingredients.remove('gold'); assert(ingredients.length == 2); ~~~ 使用contains()和containsAll()來檢查集合中是否有一個或多個對象: ~~~ var ingredients = Set(); ingredients.addAll(['gold', 'titanium', 'xenon']); // Check whether an item is in the set. assert(ingredients.contains('titanium')); // Check whether all the items are in the set. assert(ingredients.containsAll(['titanium', 'xenon'])); ~~~ 交集是一個集合,其項在另外兩個集合中。 ~~~ var ingredients = Set(); ingredients.addAll(['gold', 'titanium', 'xenon']); // Create the intersection of two sets. var nobleGases = Set.from(['xenon', 'argon']); var intersection = ingredients.intersection(nobleGases); assert(intersection.length == 1); assert(intersection.contains('xenon')); ~~~ 有關方法的完整列表請查看[Set API文檔](https://api.dartlang.org/stable/dart-core/Set-class.html) ### 映射(Maps) 通常稱為字典或散列的映射是鍵-值對的無序集合。映射將一個鍵關聯到某個值,以便于檢索。與JavaScript不同,Dart對象不是映射。 您可以使用簡單的文字語法聲明映射,也可以使用傳統的構造函數: ~~~ // Maps often use strings as keys. var hawaiianBeaches = { 'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'], 'Big Island': ['Wailea Bay', 'Pololu Beach'], 'Kauai': ['Hanalei', 'Poipu'] }; // Maps can be built from a constructor. var searchTerms = Map(); // Maps are parameterized types; you can specify what // types the key and value should be. var nobleGases = Map<int, String>(); ~~~ 使用方括號語法add、get和set映射項。使用remove()從映射中刪除鍵及其值。 ~~~ var nobleGases = {54: 'xenon'}; // Retrieve a value with a key. assert(nobleGases[54] == 'xenon'); // Check whether a map contains a key. assert(nobleGases.containsKey(54)); // Remove a key and its value. nobleGases.remove(54); assert(!nobleGases.containsKey(54)); ~~~ 你可以從一個map檢索所有的值或所有的鍵: ~~~ var hawaiianBeaches = { 'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'], 'Big Island': ['Wailea Bay', 'Pololu Beach'], 'Kauai': ['Hanalei', 'Poipu'] }; // Get all the keys as an unordered collection // (an Iterable). var keys = hawaiianBeaches.keys; assert(keys.length == 3); assert(Set.from(keys).contains('Oahu')); // Get all the values as an unordered collection // (an Iterable of Lists). var values = hawaiianBeaches.values; assert(values.length == 3); assert(values.any((v) => v.contains('Waikiki'))); ~~~ 要檢查映射是否包含某個key,請使用containsKey()。因為映射值可以為空,所以不能簡單地依賴于獲取鍵的值并檢查是否為空來確定鍵的存在。 ~~~ var hawaiianBeaches = { 'Oahu': ['Waikiki', 'Kailua', 'Waimanalo'], 'Big Island': ['Wailea Bay', 'Pololu Beach'], 'Kauai': ['Hanalei', 'Poipu'] }; assert(hawaiianBeaches.containsKey('Oahu')); assert(!hawaiianBeaches.containsKey('Florida')); ~~~ 有關方法的完整列表請查看 [Map API文檔](https://api.dartlang.org/stable/dart-core/Map-class.html) ### 集合類型的共同方法 列表、集合和映射共享許多集合中的公共功能。其中一些常見功能是由Iterable類定義的,該類列出并設置實現。 >注意:盡管Map沒有實現Iterable,但是您可以使用Map鍵和值屬性從它獲得迭代。 > 使用isEmpty或isNotEmpty檢查列表、集合或映射是否有項: ~~~ var coffees = []; var teas = ['green', 'black', 'chamomile', 'earl grey']; assert(coffees.isEmpty); assert(teas.isNotEmpty); ~~~ 要對列表、集合或映射中的每個項執行函數,可以使用forEach(): ~~~ var teas = ['green', 'black', 'chamomile', 'earl grey']; teas.forEach((tea) => print('I drink $tea')); ~~~ 在映射上調用forEach()時,函數必須接受兩個參數(鍵和值): ~~~ hawaiianBeaches.forEach((k, v) { print('I want to visit $k and swim at $v'); // I want to visit Oahu and swim at // [Waikiki, Kailua, Waimanalo], etc. }); ~~~ Iterables提供map()方法,它可以在一個對象中提供所有結果: ~~~ var teas = ['green', 'black', 'chamomile', 'earl grey']; var loudTeas = teas.map((tea) => tea.toUpperCase()); loudTeas.forEach(print); ~~~ >注意:map()返回的對象是一個可迭代的、延遲求值的對象:直到從返回的對象請求項時才調用函數。 > 強制在每個項上立即調用函數,使用map().toList()或map().toSet(): ~~~ var loudTeas = teas.map((tea) => tea.toUpperCase()).toList(); ~~~ 使用迭代器的where()方法獲得所有與條件匹配的項。使用迭代器的any()和every()方法檢查某些或所有項是否匹配一個條件。 ~~~ var teas = ['green', 'black', 'chamomile', 'earl grey']; // Chamomile is not caffeinated. bool isDecaffeinated(String teaName) => teaName == 'chamomile'; // Use where() to find only the items that return true // from the provided function. var decaffeinatedTeas = teas.where((tea) => isDecaffeinated(tea)); // or teas.where(isDecaffeinated) // Use any() to check whether at least one item in the // collection satisfies a condition. assert(teas.any(isDecaffeinated)); // Use every() to check whether all the items in a // collection satisfy a condition. assert(!teas.every(isDecaffeinated)); ~~~ 要獲得完整的方法列表,請參考[Iterable API文檔](https://api.dartlang.org/stable/dart-core/Iterable-class.html)以及[List](https://api.dartlang.org/stable/dart-core/List-class.html)、[Set](https://api.dartlang.org/stable/dart-core/Set-class.html)和[Map](https://api.dartlang.org/stable/dart-core/Map-class.html)文檔。 ## URIs Uri類提供了對字符串進行編碼和解碼的函數,以便在Uri中使用(您可能知道url)。這些函數處理uri特有的字符,例如&和=。Uri類還解析并公開Uri主機、端口、 協議等的組件。 ### 編碼和解碼完整的uri 要對URI中具有特殊含義的字符(例如/、:、&、#)進行編碼和解碼,請使用encodeFull()和decodeFull()方法。這些方法適用于編碼或解碼完整的URI,保留完整的特殊URI字符。 ~~~ var uri = 'http://example.org/api?foo=some message'; var encoded = Uri.encodeFull(uri); assert(encoded == 'http://example.org/api?foo=some%20message'); var decoded = Uri.decodeFull(encoded); assert(uri == decoded); ~~~ 注意,只有some和message中間的空格被編碼 ### 對URI組件進行編碼和解碼 要對URI中具有特殊含義的所有字符串字符進行編碼和解碼,包括(但不限于)/、&和:,請使用encodeComponent()和decodeComponent()方法。 ~~~ var uri = 'http://example.org/api?foo=some message'; var encoded = Uri.encodeComponent(uri); assert(encoded == 'http%3A%2F%2Fexample.org%2Fapi%3Ffoo%3Dsome%20message'); var decoded = Uri.decodeComponent(encoded); assert(uri == decoded); ~~~ 注意每個特殊字符是如何編碼的。例如,/被編碼為%2F。 ### 解析uri 如果您有一個Uri對象或一個Uri字符串,您可以使用Uri字段(如path)獲得它的部分。要從字符串創建Uri,使用parse()靜態方法: ~~~ var uri = Uri.parse('http://example.org:8080/foo/bar#frag'); assert(uri.scheme == 'http'); assert(uri.host == 'example.org'); assert(uri.path == '/foo/bar'); assert(uri.fragment == 'frag'); assert(uri.origin == 'http://example.org:8080'); ~~~ 查看[Uri API文檔](https://api.dartlang.org/stable/dart-core/Uri-class.html)可以獲得更多的Uri組件。 ### 構建uri 您可以使用Uri()構造函數從各個部分構建一個URI: ~~~ var uri = Uri( scheme: 'http', host: 'example.org', path: '/foo/bar', fragment: 'frag'); assert( uri.toString() == 'http://example.org/foo/bar#frag'); ~~~ ## 日期和時間 DateTime對象是一個時間點。時區不是UTC就是當地時區。 你可以使用幾個構造函數來創建DateTime對象: ~~~ // Get the current date and time. var now = DateTime.now(); // Create a new DateTime with the local time zone. var y2k = DateTime(2000); // January 1, 2000 // Specify the month and day. y2k = DateTime(2000, 1, 2); // January 2, 2000 // Specify the date as a UTC time. y2k = DateTime.utc(2000); // 1/1/2000, UTC // Specify a date and time in ms since the Unix epoch. y2k = DateTime.fromMillisecondsSinceEpoch(946684800000, isUtc: true); // Parse an ISO 8601 date. y2k = DateTime.parse('2000-01-01T00:00:00Z'); ~~~ 日期的millisecondsSinceEpoch屬性返回自“Unix epoch”(1970年1月1日,UTC)以來的毫秒數: ~~~ // 1/1/2000, UTC var y2k = DateTime.utc(2000); assert(y2k.millisecondsSinceEpoch == 946684800000); // 1/1/1970, UTC var unixEpoch = DateTime.utc(1970); assert(unixEpoch.millisecondsSinceEpoch == 0); ~~~ 使用Duration類來計算兩個日期之間的差值,并將一個日期向前或向后移動: ~~~ var y2k = DateTime.utc(2000); // Add one year. var y2001 = y2k.add(Duration(days: 366)); assert(y2001.year == 2001); // Subtract 30 days. var december2000 = y2001.subtract(Duration(days: 30)); assert(december2000.year == 2000); assert(december2000.month == 12); // Calculate the difference between two dates. // Returns a Duration object. var duration = y2001.difference(y2k); assert(duration.inDays == 366); // y2k was a leap year. ~~~ >警告:使用持續時間以天為單位來移動日期時間是有問題的,因為時鐘會改變(例如,夏令時)。如果你必須換班,請使用UTC日期。 > 有關[DateTime](https://api.dartlang.org/stable/dart-core/DateTime-class.html) 和[Duration](https://api.dartlang.org/stable/dart-core/Duration-class.html)的完整方法列表,請參閱API文檔。 ## 實用程序類 核心庫包含各種實用程序類,用于排序、映射值和迭代。 ### 比較對象 實現Comparable接口,以指示一個對象可以與另一個對象進行比較,通常用于排序。compareTo()方法返回< 0對于小的,0對于相等的,大的返回>0。 ~~~ class Line implements Comparable<Line> { final int length; const Line(this.length); @override int compareTo(Line other) => length - other.length; } void main() { var short = const Line(1); var long = const Line(100); assert(short.compareTo(long) < 0); } ~~~ ### 實現map鍵 Dart中的每個對象自動地提供了一個整數哈希碼,因此可以作為映射中的鍵。但是,您可以重寫hashCode getter來生成自定義哈希代碼。如果這樣做,您可能還想重寫==操作符。相等的對象(via ==)必須具有相同的哈希碼。哈希代碼不一定是唯一的,但它應該是分布良好的。 ~~~ class Person { final String firstName, lastName; Person(this.firstName, this.lastName); // Override hashCode using strategy from Effective Java, // Chapter 11. @override int get hashCode { int result = 17; result = 37 * result + firstName.hashCode; result = 37 * result + lastName.hashCode; return result; } // You should generally implement operator == if you // override hashCode. @override bool operator ==(dynamic other) { if (other is! Person) return false; Person person = other; return (person.firstName == firstName && person.lastName == lastName); } } void main() { var p1 = Person('Bob', 'Smith'); var p2 = Person('Bob', 'Smith'); var p3 = 'not a person'; assert(p1.hashCode == p2.hashCode); assert(p1 == p2); assert(p1 != p3); } ~~~ ### 迭代 Iterable類和Iterator類支持for-in循環。無論何時,只要您創建了一個類,可以為for-in循環提供迭代器,就可以擴展(如果可能的話)或實現Iterable。實現迭代器來定義實際的迭代能力。 ~~~ class Process { // Represents a process... } class ProcessIterator implements Iterator<Process> { @override Process get current => ... @override bool moveNext() => ... } // A mythical class that lets you iterate through all // processes. Extends a subclass of [Iterable]. class Processes extends IterableBase<Process> { @override final Iterator<Process> iterator = ProcessIterator(); } void main() { // Iterable objects can be used with for-in. for (var process in Processes()) { // Do something with the process. } } ~~~ ## 異常 Dart核心庫定義了許多常見的異常和錯誤。異常被認為是可以提前計劃和捕捉的條件。錯誤是您沒有預料到或計劃的情況。 一些最常見的錯誤是: [NoSuchMethodError](https://api.dartlang.org/stable/dart-core/NoSuchMethodError-class.html) 當接收對象(可能為空)沒有實現方法時拋出。 [ArgumentError](https://api.dartlang.org/stable/dart-core/ArgumentError-class.html) 可以由遇到意外參數的方法拋出。 拋出特定于應用程序的異常是表示發生了錯誤的常見方法。您可以通過實現異常接口來定義自定義異常: ~~~ class FooException implements Exception { final String msg; const FooException([this.msg]); @override String toString() => msg ?? 'FooException'; } ~~~ 更多信息請查看 [Exceptions](https://www.dartlang.org/guides/libraries/library-tour#exceptions) 和 [Exception API 文檔](https://api.dartlang.org/stable/dart-core/Exception-class.html)。 # 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)對象。Future就像對未來某個時刻的結果的承諾。Stream是一種獲取值序列(如事件)的方法。dart:async庫([API參考](https://api.dartlang.org/stable/dart-async/dart-async-library.html))中包含了Future, Stream和更多內容。 >注意:您并不總是需要直接使用Future api或Stream api。Dart語言支持使用諸如async和await等關鍵字進行異步編碼。有關詳細信息,請參閱語本文檔中的[異步支持](http://www.hmoore.net/marswill/dark2_document/709109)。 > dart:async庫在web應用程序和命令行應用程序中都能工作。要使用它,導入dart:async: ~~~ import 'dart:async'; ~~~ ## Future Future對象出現在Dart庫中,通常是異步方法返回的對象。當Future完成時,它的值就可以使用了。 ### 使用await 在直接使用Future API之前,請考慮使用await。使用await表達式的代碼比使用Future API的代碼更容易理解。 考慮下面的函數。它使用Future的then()方法在一行中執行三個異步函數,等待每個函數完成后再執行下一個。 ~~~ runUsingFuture() { // ... findEntryPoint().then((entryPoint) { return runExecutable(entryPoint, args); }).then(flushThenExit); } ~~~ 具有await表達式的等效代碼看起來更像同步代碼: ~~~ runUsingAsyncAwait() async { // ... var entryPoint = await findEntryPoint(); var exitCode = await runExecutable(entryPoint, args); await flushThenExit(exitCode); } ~~~ 異步函數可以捕獲Futures中的異常。例如: ~~~ var entryPoint = await findEntryPoint(); try { var exitCode = await runExecutable(entryPoint, args); await flushThenExit(exitCode); } catch (e) { // Handle the error... } ~~~ >重要提示:異步函數返回Future。如果您不希望函數返回Future,那么使用不同的解決方案。例如,您可以從您的函數調用一個異步函數。 > 有關使用await和相關Dart語言特性的更多信息,請參閱[異步支持](https://www.dartlang.org/guides/language/language-tour#asynchrony-support)。 ### 基本使用 您可以使用then()來調度Future完成時運行的代碼。例如,HttpRequest.getString()返回一個Future,因為HTTP請求可能需要一段時間。使用then()可以讓您在Future完成并且承諾的字符串值可用時運行一些代碼: ~~~ HttpRequest.getString(url).then((String result) { print(result); }); ~~~ 使用catchError()來處理Future對象可能拋出的任何錯誤或異常。 ~~~ HttpRequest.getString(url).then((String result) { print(result); }).catchError((e) { // Handle or ignore the error. }); ~~~ then().catchError()模式是try-catch的異步版本。 >重要提示:一定要在then()的結果上調用catchError()——而不是在原始Future的結果上。否則,catchError()只能從原始Future的計算中處理錯誤,而不能從then()注冊的處理程序處理錯誤。 > ### 鏈接多個異步方法 then()方法返回一個Future,提供了一種有用的方式來以特定的順序運行多個異步函數。如果用then()注冊的回調返回一個Future,那么then()返回一個等效的Future。如果回調返回任何其他類型的值,那么then()將創建一個新的Future,并使用該值完成操作。 ~~~ Future result = costlyQuery(url); result .then((value) => expensiveWork(value)) .then((_) => lengthyComputation()) .then((_) => print('Done!')) .catchError((exception) { /* Handle exception... */ }); ~~~ 在前面的例子中,方法按照以下順序運行: 1. costlyQuery() 2. expensiveWork() 3. lengthyComputation() 下面是使用await編寫的相同代碼: ~~~ try { final value = await costlyQuery(url); await expensiveWork(value); await lengthyComputation(); print('Done!'); } catch (e) { /* Handle exception... */ } ~~~ ### 等待多個Future 有時您的算法需要調用許多異步函數,并等待它們全部完成后再繼續。使用Future.wait()靜態方法管理多個期貨,并等待它們完成: ~~~ Future deleteLotsOfFiles() async => ... Future copyLotsOfFiles() async => ... Future checksumLotsOfOtherFiles() async => ... await Future.wait([ deleteLotsOfFiles(), copyLotsOfFiles(), checksumLotsOfOtherFiles(), ]); print('Done with all the long steps!'); ~~~ ## Stream 流對象出現在Dart api中,表示數據序列。例如,HTML事件(如按鈕單擊)是使用流傳遞的。您還可以將文件讀取為流。 ### 使用異步for循環 有時候,您可以使用異步for循環(wait for),而不是使用流API。 考慮下面的函數。它使用Stream的listen()方法訂閱一個文件列表,傳入一個搜索每個文件或目錄的函數文字。 ~~~ void main(List<String> arguments) { // ... FileSystemEntity.isDirectory(searchPath).then((isDir) { if (isDir) { final startingDir = Directory(searchPath); startingDir .list( recursive: argResults[recursive], followLinks: argResults[followLinks]) .listen((entity) { if (entity is File) { searchFile(entity, searchTerms); } }); } else { searchFile(File(searchPath), searchTerms); } }); } ~~~ 帶有await表達式的等價代碼,包括異步for循環(await for),看起來更像同步代碼: ~~~ Future main(List<String> arguments) async { // ... if (await FileSystemEntity.isDirectory(searchPath)) { final startingDir = Directory(searchPath); await for (var entity in startingDir.list( recursive: argResults[recursive], followLinks: argResults[followLinks])) { if (entity is File) { searchFile(entity, searchTerms); } } } else { searchFile(File(searchPath), searchTerms); } } ~~~ >重要提示:在使用await for之前,確保它使代碼更清晰,并且您確實希望等待流的所有結果。例如,對于DOM事件偵聽器,通常不應該使用await For,因為DOM發送無窮無盡的事件流。如果您使用await for在一行中注冊兩個DOM事件偵聽器,那么第二類事件永遠不會被處理。 > 有關使用await和相關Dart語言特性的更多信息,請參閱[異步支持](https://www.dartlang.org/guides/language/language-tour#asynchrony-support)。 ### 監聽流數據 要在每個值到達時獲得它,可以使用await()方法對流使用或使用listen()方法訂閱: ~~~ // Find a button by ID and add an event handler. querySelector('#submitInfo').onClick.listen((e) { // When the button is clicked, it runs this code. submitData(); }); ~~~ 在本例中,onClick屬性是“submitInfo”按鈕提供的流對象。 如果只關心一個事件,那么可以使用屬性first、last或single來獲得它。要在處理事件之前測試它,可以使用諸如firstWhere()、lastWhere()或singleWhere()之類的方法。 如果關心事件的子集,可以使用諸如skip()、skipWhile()、take()、takeWhile()和where()等方法。 ### 改變流數據 通常,您需要在使用流數據之前更改其格式。使用transform()方法生成具有不同類型數據的流: ~~~ var lines = inputStream .transform(utf8.decoder) .transform(LineSplitter()); ~~~ 這個例子使用了兩個轉換器。首先,它使用utf8.decoder將整數流轉換為字符串流。然后,它使用linesp才將字符串流轉換為單獨的行流。這些轉換器來自dart:convert庫(參見[dart:convert部分](https://www.dartlang.org/guides/libraries/library-tour#dartconvert---decoding-and-encoding-json-utf-8-and-more))。 ### 處理錯誤和完成 如何指定錯誤和完成處理代碼取決于是使用異步for循環(wait for)還是流API。 如果使用異步for循環,則使用try-catch處理錯誤。在流關閉后執行的代碼在異步for循環之后執行。 ~~~ Future readFileAwaitFor() async { var config = File('config.txt'); Stream<List<int>> inputStream = config.openRead(); var lines = inputStream .transform(utf8.decoder) .transform(LineSplitter()); try { await for (var line in lines) { print('Got ${line.length} characters from stream'); } print('file is now closed'); } catch (e) { print(e); } } ~~~ 如果使用流API,則通過注冊onError偵聽器來處理錯誤。通過注冊onDone偵聽器,在流關閉后運行代碼。 ~~~ var config = File('config.txt'); Stream<List<int>> inputStream = config.openRead(); inputStream .transform(utf8.decoder) .transform(LineSplitter()) .listen((String line) { print('Got ${line.length} characters from stream'); }, onDone: () { print('file is now closed'); }, onError: (e) { print(e); }); ~~~ ### 更多信息 有關在命令行應用程序中使用Future和Stream的一些示例,請參閱[dart:io的引導](https://www.dartlang.org/dart-vm/io-library-tour)。也看這些文章和教程: * [Asynchronous Programming: Futures](https://www.dartlang.org/tutorials/language/futures) * [Futures and Error Handling](https://www.dartlang.org/guides/libraries/futures-error-handling) * [The Event Loop and Dart](https://webdev.dartlang.org/articles/performance/event-loop) * [Asynchronous Programming: Streams](https://www.dartlang.org/tutorials/language/streams) * [Creating Streams in Dart](https://www.dartlang.org/articles/libraries/creating-streams) # dart:math - math and random dart:math 庫 ([API 參考](https://api.dartlang.org/stable/dart-math/dart-math-library.html))提供了常見的功能,如正弦和余弦,最大值和最小值,以及常量,如pi和e。Math 庫中的大多數功能是作為頂級函數實現的。 要在應用程序中使用這個庫,導入dart:math。 ~~~ import 'dart:math'; ~~~ ## 三角函數 數學庫提供基本三角函數: ~~~ // Cosine assert(cos(pi) == -1.0); // Sine var degrees = 30; var radians = degrees * (pi / 180); // radians is now 0.52359. var sinOf30degrees = sin(radians); // sin 30° = 0.5 assert((sinOf30degrees - 0.5).abs() < 0.01); ~~~ >注意:這些函數使用弧度,而不是角度! > ## 最大和最小值 數學庫提供max()和min()方法: ~~~ assert(max(1, 1000) == 1000); assert(min(1, -1000) == -1000); ~~~ ## 數學常量 在數學庫中找到你最喜歡的常量- pi, e,以及更多: ~~~ // See the Math library for additional constants. print(e); // 2.718281828459045 print(pi); // 3.141592653589793 print(sqrt2); // 1.4142135623730951 ~~~ ## 隨機數 用Random類生成隨機數。您可以選擇向隨機構造函數提供種子。 ~~~ var random = Random(); random.nextDouble(); // Between 0.0 and 1.0: [0, 1) random.nextInt(10); // Between 0 and 9. ~~~ 你甚至可以產生隨機布爾: ~~~ var random = Random(); random.nextBool(); // true or false ~~~ ## 更多信息 有關方法的完整列表,請參閱[Math API文檔](https://api.dartlang.org/stable/dart-math/dart-math-library.html)。還可以查看有關[num](https://api.dartlang.org/stable/dart-core/num-class.html)、[int](https://api.dartlang.org/stable/dart-core/int-class.html)和[double](https://api.dartlang.org/stable/dart-core/double-class.html)的API文檔。 # dart:convert - 解碼和編碼JSON、UTF-8等等 dart:convert庫([API reference](https://api.dartlang.org/stable/dart-convert/dart-convert-library.html))為JSON和UTF-8提供了轉換器,并且支持創建額外的轉換器。[JSON](https://www.json.org/)是一種表示結構化對象和集合的簡單文本格式。[UTF-8](https://en.wikipedia.org/wiki/UTF-8)是一種常見的變寬編碼,可以表示Unicode字符集中的每個字符。 dart:convert 庫可以在web應用程序和命令行應用程序中工作。要使用它,導入dart:convert。 ~~~ import 'dart:convert'; ~~~ ## 編碼接嗎JSON 用jsonDecode()將json編碼的字符串解碼為Dart對象: ~~~ // NOTE: Be sure to use double quotes ("), // not single quotes ('), inside the JSON string. // This string is JSON, not Dart. var jsonString = ''' [ {"score": 40}, {"score": 80} ] '''; var scores = jsonDecode(jsonString); assert(scores is List); var firstScore = scores[0]; assert(firstScore is Map); assert(firstScore['score'] == 40); ~~~ 用jsonEncode()將受支持的Dart對象編碼為json格式的字符串: ~~~ var scores = [ {'score': 40}, {'score': 80}, {'score': 100, 'overtime': true, 'special_guest': null} ]; var jsonText = jsonEncode(scores); assert(jsonText == '[{"score":40},{"score":80},' '{"score":100,"overtime":true,' '"special_guest":null}]'); ~~~ 只有int、double、String、bool、null、List或Map(帶字符串鍵)類型的對象可以直接編碼為JSON。列表和映射對象是遞歸編碼的。 對于不能直接編碼的對象,有兩個編碼選項。第一個是使用第二個參數調用encode():一個返回可直接編碼對象的函數。第二個選項是省略第二個參數,在這種情況下,編碼器調用對象的toJson()方法。 ## 解碼和編碼UTF-8字符 使用utf8.decode()將utf8編碼的字節解碼到Dart字符串: ~~~ List<int> utf8Bytes = [ 0xc3, 0x8e, 0xc3, 0xb1, 0xc5, 0xa3, 0xc3, 0xa9, 0x72, 0xc3, 0xb1, 0xc3, 0xa5, 0xc5, 0xa3, 0xc3, 0xae, 0xc3, 0xb6, 0xc3, 0xb1, 0xc3, 0xa5, 0xc4, 0xbc, 0xc3, 0xae, 0xc5, 0xbe, 0xc3, 0xa5, 0xc5, 0xa3, 0xc3, 0xae, 0xe1, 0xbb, 0x9d, 0xc3, 0xb1 ]; var funnyWord = utf8.decode(utf8Bytes); assert(funnyWord == '???ér???????????????'); ~~~ 要將UTF-8字符流轉換為Dart字符串,請將utf8.decoder指定為stream transform()方法: ~~~ var lines = inputStream .transform(utf8.decoder) .transform(LineSplitter()); try { await for (var line in lines) { print('Got ${line.length} characters from stream'); } print('file is now closed'); } catch (e) { print(e); } ~~~ 使用utf8.encode()將Dart字符串編碼為utf8編碼字節的列表: ~~~ List<int> encoded = utf8.encode('???ér???????????????'); assert(encoded.length == utf8Bytes.length); for (int i = 0; i < encoded.length; i++) { assert(encoded[i] == utf8Bytes[i]); } ~~~ ## 其他功能 dart:convert庫也有ASCII和ISO-8859-1 (Latin1)轉換器。有關dart:convert庫的詳細信息,請參閱[API文檔](https://api.dartlang.org/stable/dart-convert/dart-convert-library.html)。 # 總結 這個頁面向您介紹了Dart內置庫中最常用的功能。然而,它并沒有覆蓋所有內置庫。您可能想了解的其他內容包括[dart:collection](https://api.dartlang.org/stable/dart-collection/dart-collection-library.html)和[dart:typed_data](https://api.dartlang.org/stable/dart-typed_data/dart-typed_data-library.html),以及特定于平臺的libaries(如[dart web開發庫](https://webdev.dartlang.org/guides/web-programming)和[Flutter庫](https://docs.flutter.io/))。 您可以使用[pub工具](https://www.dartlang.org/tools/pub)獲得更多的庫。[collection](https://pub.dartlang.org/packages/collection), [crypto](https://pub.dartlang.org/packages/crypto), [http](https://pub.dartlang.org/packages/http), [intl](https://pub.dartlang.org/packages/intl), 和 [test](https://pub.dartlang.org/packages/test)庫只是使用pub安裝內容的一個示例。 要了解更多關于Dart語言的信息,請參見本文檔其他章節。
                  <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>

                              哎呀哎呀视频在线观看