了解Dart
強(qiáng)類型編程語言,Dart之下一切皆對象
Dart 是一種跨平臺的客戶端開發(fā)語言鼻种。具有專門為客戶端優(yōu)化立倍、高生產(chǎn)力哪廓、快速高效狗唉、可移植易學(xué)的風(fēng)格。Dart主要由Google負(fù)責(zé)開發(fā)和維護(hù)
重要概念
在 Dart 中 甚至連 數(shù)字涡真、方法和
null
都是對象分俯。所有的對象都繼承于 Object 類Object所有Dart對象的基類,所以每個其他Dart類都是Object的子類,Object在編譯時檢查類型
雖然dart語言通過var進(jìn)行運(yùn)行時類型推導(dǎo),但是Dart是強(qiáng)類型的語言,類型一旦確定就不可以改變
Dart 沒有 public、 protected哆料、 和 private 關(guān)鍵字缸剪。如果一個標(biāo)識符以 (_) 開頭,則該標(biāo)識符 在庫內(nèi)是私有的
Dart 工具可以指出兩種問題:警告和錯誤东亦。 警告只是說你的代碼可能有問題杏节, 但是并不會阻止你的代碼執(zhí)行。 錯誤可以是編譯時錯誤也可以是運(yùn)行時錯誤讥此。遇到編譯時錯誤時拢锹,代碼將 無法執(zhí)行谣妻;運(yùn)行時錯誤將會在運(yùn)行代碼的時候?qū)е乱粋€異常
基本語法
Dart內(nèi)置的數(shù)據(jù)類型
Dart支持的內(nèi)置類型有numbers萄喳、 strings、booleans蹋半、lists他巨、maps、runes减江、symbols(最新的被移除)
- numbers 數(shù)值
num有兩個子類, int 和 double
int值: 其取值通常位于 -253 和 253 之間
double : 64-bit (雙精度) 浮點(diǎn)數(shù)染突,符合 IEEE 754 標(biāo)準(zhǔn)
- strings 字符串
Dart 字符串是 UTF-16 編碼的字符序列。 可以使用單引號辈灼、雙引號份企、三引號來創(chuàng)建字符串
String string0 = "牛糞糞";
String string1 = '牛轟轟';
String string2 = '''牛轟轟
love
牛糞糞''';
print(string0);
print(string1);
print(string2);
print(string0==string1);
print(string0=="牛糞糞");
注意:
1、== 操作符判斷兩個對象的內(nèi)容是否一樣巡莹。 如果兩個字符串包含一樣的字符編碼序列司志, 則他們是相等的
2、可以使用 + 操作符來把多個字符串鏈接為一個降宅,也可以把多個 字符串放到一起來實現(xiàn)同樣的功能
通過提供一個 r 前綴可以創(chuàng)建一個 “原始 raw” 字符串:
var s = r"牛糞糞 \n 你在哪";
print(s);// \n也會被打印
num 與string之間相互轉(zhuǎn)換
// String 轉(zhuǎn) int
var one = int.parse('1');
assert(one == 1);
// String 轉(zhuǎn) double
var onePointOne = double.parse('1.1');
assert(onePointOne == 1.1);
// int 轉(zhuǎn) String
String oneAsString = 1.toString();
assert(oneAsString == '1');
// double 轉(zhuǎn) String
String piAsString = 3.14159.toStringAsFixed(2);
assert(piAsString == '3.14');
- booleans 布爾值
Dart 有一個名字為 bool 的類型,只有兩個對象是布爾類型的:true 和 false 所創(chuàng)建的對象骂远, 這兩個對象也都是編譯時常量。
當(dāng) Dart 需要一個布爾值的時候腰根,只有 true 對象才被認(rèn)為是 true激才。 所有其他的值都是 flase。這點(diǎn)和 JavaScript 不一樣
- lists 集合和泌、列表
編程語言中最常見的集合類型限嫌。 在 Dart 中數(shù)組就是 List 對象。所以 通常我們都稱之為 lists
Lists 的下標(biāo)索引從 0 開始傲绣,第一個元素的索引是 0. list.length - 1 是最后一個元素的索引东帅。 訪問 list 的長度和元素與 JavaScript 中的用法一樣
list.asMap()可以將list集合轉(zhuǎn)為map,list角標(biāo)作為map的key
Set集合和java差不多,特點(diǎn)就是元素對象不重復(fù)
Set set0 = {1, 1, 1, 1, 12, 13, 0};
print(set0);
Set set1 = {12, 13, 0, 3, 4};
print(set1);
print(set1.difference(set0)); //補(bǔ)集
print(set1.union(set0)); //并集
print(set1.intersection(set0)); //交集
- maps
Map 是一個鍵值對相關(guān)的對象揣云。 鍵和值可以是任何類型的對象。每個 鍵 只出現(xiàn)一次冰啃, 而一個值則可以出現(xiàn)多次
- runes 符號字符串的 UTF-32 code points
Unicode 為每一個字符邓夕、標(biāo)點(diǎn)符號、表情符號等都定義了 一個唯一的數(shù)值阎毅。 由于 Dart 字符串是 UTF-16 code units 字符序列焚刚, 所以在字符串中表達(dá) 32-bit Unicode 值就需要新的語法了
Runes input = new Runes(
'\u2665 \u{1f605} \u{1f609} \u{1f47b} \u{1f596} \u{1f44d}');
print(new String.fromCharCodes(input));
//
- symbols dart:mirrors庫提供了基本的反射使用
關(guān)鍵字
- 標(biāo) 1 的關(guān)鍵字是 內(nèi)置關(guān)鍵字。避免把內(nèi)置關(guān)鍵字當(dāng)做標(biāo)識符使用扇调。 也不要把內(nèi)置關(guān)鍵字 用作類名字和類型名字矿咕。 有些內(nèi)置關(guān)鍵字是為了方便把 JavaScript 代碼移植到 Dart 而存在的。 例如狼钮,如果 JavaScript 代碼中有個變量的名字為 factory碳柱, 在移植到 Dart 中的時候,你不必重新命名這個變量熬芜。
- 標(biāo) 2 的關(guān)鍵字莲镣,是在 Dart 1.0 發(fā)布以后又新加的,用于 支持異步相關(guān)的特性涎拉。 你不能在標(biāo)記為 async瑞侮、 async、或者 sync 的方法體內(nèi) 使用 async鼓拧、 await半火、或者 yield 作為標(biāo)識符
變量聲明
- 默認(rèn)聲明
String str;
沒有初始化的變量自動獲取一個默認(rèn)值為null,雖然聲明的時string,但是string類型也是一個對象
- 賦值聲明
String str = "牛糞糞";
bool isOK
bool isOK; //因為默認(rèn)都屬null,所以不能直接用在if語句中如
if (isOK) {
}
運(yùn)行報錯:
Failed assertion: boolean expression must not be null
- 常量聲明Final and const
final String string0 = "牛糞糞";
const String string1 = "牛轟轟";
Final and const 修飾的都是常量
- final 修飾的常量是運(yùn)行時常量,運(yùn)行時只能賦值一次
- const 關(guān)鍵字不僅僅只用來定義常量。 可以用來創(chuàng)建不變的值季俩, 還能定義構(gòu)造函數(shù)為 const 類型的钮糖,這種類型 的構(gòu)造函數(shù)創(chuàng)建的對象是不可改變的。任何變量都可以有一個不變的值
- const 修飾的常量為編譯時常量
final List str0 = ["牛糞糞", "牛轟轟"];
final List str1 = ["牛糞糞", "牛轟轟"];
print(identical(str1, str0)); //輸出false
//說明str0和str1引用指向不同的對象酌住,也就是說內(nèi)存中有兩份相同的值
const List str2 = ["牛糞糞", "牛轟轟"];
const List str3 = ["牛糞糞", "牛轟轟"];
print(identical(str2, str3)); //輸出true
//說明str2 str3 引用指向同一個內(nèi)存中的對象
方法聲明
Dart 是一個真正的面向?qū)ο笳Z言店归,方法也是對象并且具有一種 類型,
Function
赂韵。 這意味著娱节,方法可以賦值給變量,也可以當(dāng)做其他方法的參數(shù)祭示。 也可以把 Dart 類的實例當(dāng)做方法來調(diào)用
- 程序入口main方法
//每個應(yīng)用都需要有個頂級的 main() 入口方法才能執(zhí)行
//main() 方法的返回值為 void 并且有個可選的 List<String> 參數(shù)
// 這是程序執(zhí)行的入口
main() {
}
//下面是一個命令行應(yīng)用的 main() 方法肄满,并且使用了 方法參數(shù)作為輸入?yún)?shù):
void main(List<String> arguments) {
print(arguments);
assert(arguments.length == 2);
assert(int.parse(arguments[0]) == 1);
assert(arguments[1] == 'test');
}
- 命名參數(shù)方法
方法可以有兩種類型的參數(shù):必需的和可選的谴古。 必需的參數(shù)在參數(shù)列表前面, 后面是可選參數(shù)
- 可選命名參數(shù)
可選參數(shù)可以是命名參數(shù)或者基于位置的參數(shù)稠歉,但是這兩種參數(shù)不能同時當(dāng)做可選參數(shù)
定義:使用 {param1, param2, …} 的形式來指定命名參數(shù)
hello2({int a, int b}) { print(a); print(b); }
調(diào)用:使用這種形式 paramName: value 來指定命名參數(shù)
print(hello2(a: 1)); //輸出結(jié)果 1 null null
- 可選位置參數(shù)
定義:把一些方法的參數(shù)放到 [] 中就變成可選位置參數(shù)了
hello3(String name, [int age, String str]) { print(name); print(age); print(str); }
調(diào)用:
//不使用可選參數(shù)調(diào)用 print(hello3("牛糞糞")); //使用可選參數(shù)調(diào)用 print(hello3("牛糞糞", 27, "愛吃豬蹄")); //使用可選參數(shù)調(diào)用 print(hello3("牛糞糞", null, "愛吃豬蹄"));
可選命名比可選位置更加靈活: 命名可以跳過一些參數(shù),但是可選位置只能順序傳參,想要跳過就傳入null
- 默認(rèn)參數(shù)
定義:在定義方法的時候掰担,可以使用 = 來定義可選參數(shù)的默認(rèn)值。 默認(rèn)值只能是編譯時常量怒炸。 如果沒有提供默認(rèn)值带饱,則默認(rèn)值為 null
void hello3(String name, [int age, String str = "123"]) { print(name); print(age); print(str); }
還可以使用 list 或者 map 作為默認(rèn)值
- 匿名方法
大部分方法都帶有名字,例如 main() 或者 printElement()阅羹。 你有可以創(chuàng)建沒有名字的方法勺疼,稱之為 匿名方法,有時候也被稱為 lambda 或者 closure 閉包捏鱼。 你可以把匿名方法賦值給一個變量执庐, 然后你可以使用這個方法,比如添加到集合或者從集合中刪除导梆。
匿名函數(shù)和命名函數(shù)看起來類似— 在括號之間可以定義一些參數(shù)轨淌,參數(shù)使用逗號 分割,也可以是可選參數(shù)看尼。 后面大括號中的代碼為函數(shù)體:
([[Type] param1[, …]]) {
codeBlock;
};
注意:
1递鹉、胖箭頭語法
對于只有一個表達(dá)式的方法,你可以選擇 使用縮寫語法來定義:int add(int a, int b) => a + b; //等價與 int add(int a, int b) { return a+b;}
在箭頭 (=>) 和冒號 (;) 之間只能使用一個表達(dá)式,不能使用語句
2藏斩、級聯(lián)調(diào)用
代碼中的
..語法為級聯(lián)調(diào)用躏结。 使用級聯(lián)調(diào)用語法, 你可以在一個對象上執(zhí)行多個操作
3灾茁、Dart支持方法中定義方法,并且可以多級嵌套
4窜觉、所有的函數(shù)都返回一個值。如果沒有指定返回值北专,則默認(rèn)把語句 return null; 作為函數(shù)的最后一個語句執(zhí)行
操作符
下表是 Dart 中定義的操作符。 很多操作符都可以重載
在操作符表格中所列的操作符 都是按照優(yōu)先級順序從左到右旬陡,從上到下的方式來列出的拓颓, 上面和左邊的操作符優(yōu)先級要高于下面和右邊的。 例如 %
操作符優(yōu)先級高于 ==
描孟,而 等號 高于 &&
可覆寫的操作符
下表中的操作符可以被覆寫驶睦。 例如,如果你定義了一個 Vector 類匿醒, 你可以定義一個 + 函數(shù)來實現(xiàn)兩個向量相加
如果你覆寫了 == 场航,則還應(yīng)該覆寫對象的 hashCode getter 函數(shù)
斷言assert
注意: 在生產(chǎn)模式
assert()
語句被忽略了。在檢查模式assert(*condition*)
會執(zhí)行
assert
方法的參數(shù)可以為任何返回布爾值的表達(dá)式或者方法廉羔。 如果返回的值為 true溉痢, 斷言執(zhí)行通過,執(zhí)行結(jié)束。 如果返回值為 false孩饼, 斷言執(zhí)行失敗髓削,會拋出一個異常 AssertionError