安裝
如果是windows
系統(tǒng),點擊安裝SDK:http://www.gekorm.com/dart-windows/
如果是Mac
系統(tǒng),點擊安裝SDK:https://dart.dev/get-dart
可將dart
安裝后的bin
目錄加入到path
路徑中,打開命令行工具,使用命令dart --version
確保dart
已安裝到您電腦中即可。
為什么要學(xué)些這門語言
目前Google
推出的最新跨端解決方案Flutter
,需要采用Dart語言
編寫前端代碼。Flutter
是目前市面上最好的跨端應(yīng)用解決方案,另外,Dart語言
學(xué)習(xí)門檻低性能好,支持動靜態(tài)編譯,并支持很多高級語言特性。
語法要點
dart語言
借鑒了java
,js
,swift
等高級的語言特性,并融入很多使用的語法糖,我們來簡要做個概括。
- 在Dart中所有變量引用的都是對象,繼承
Object
,包括數(shù)字,函數(shù),null
等都是對象; - 在Dart運行之前會解析您的代碼,通過使用類型和編譯型常量來幫助Dart捕獲異常,讓代碼運行的更高效;
- Dart支持在方法中定義方法,函數(shù)是Dart非常重要的概念;
- Dart沒有
public
,private
,protected
關(guān)鍵字,如果要申明私有成員變量或函數(shù)請使用_打頭; - 可以在代碼中加入
assert
斷言語句以便讓有些錯誤在編譯器就能被捕獲;
啟動入口
Dart語言也是把main函數(shù)作為入口程序。可以給main函數(shù)傳入List<String>
入?yún)斫邮彰钚袇?shù)列表。
內(nèi)置類型
dart語言
使用var
聲明變量,和swift
的id
類似,在編譯階段會自動確認其類型。
dart語言
只有以下幾種內(nèi)置類型:String
,Number
,bool
,Map
,List
,Function
,Symbols
,runes
等,其中Number
分為int
和double
,注意沒有float
之類的浮點數(shù)類型,可以對Number
類型四則運算,其中取整運算符是~/
,有一些常用的屬性,如isNaN,isEven(是否偶數(shù)),isOdd(是否奇數(shù))等,可以做一些簡單的類型轉(zhuǎn)換,如int.parse("1");double.parse("1.1"
等,注意在Dart中沒有數(shù)組類型,而統(tǒng)一使用List;
-
字符串:使用
"""
多行字符串聲明,可以使用$xx
或${xx}
在字符串中使用變量占位符,相鄰的字符串拼接的+
可省略,但拼接的內(nèi)容不能是1個空格。 - 靜態(tài)變量:可以使用關(guān)鍵字static修飾類訪問的變量。
- Dart字符串是UTF-16 code units字符序列,所以支持emoji表情符,如笑臉: \u{1f600};
類的使用
Dart和Java等高級語言一樣,可以定義類,并使用extends
繼承類,使用@override
注解聲明你要重寫的函數(shù),使用super
調(diào)用重寫這個父類的函數(shù)。
如果要在代碼嘗試使用類中不存在的方法或?qū)嵗兞繖z測時做出反應(yīng),可以重寫noSuchMethod
。
可以使用abstract
修飾符定義無法實例化的類;
一個類可以使用implements
實現(xiàn)多個接口;
可以使用enum
定義枚舉;
一個類可以通過..
使用級聯(lián)調(diào)用語法,比如querySelector("#id")..text="xxx"..onClick.listen(xxx);
泛型
泛型有以下好處:
- 減少代碼重復(fù):泛型允許您在多種類型之間共享單個接口和實現(xiàn),同時仍然利用靜態(tài)分析;
- 代碼更友好,編譯期提醒:比如列表中的元素指定泛型類型可確保不符合類型的元素被添加;
- 與Java不同,Dart會在運行期攜帶類型信息,如
List<String>
類型的列表,可以使用lists.runtimeType()
,獲取到類型信息List<String>
; - 可以配合
extends
來限定參數(shù)類型; - 泛型可以被使用在包括函數(shù),函數(shù)表達式,類方法,類型參數(shù),返回類型等中;
重寫操作符
我們可以通過關(guān)鍵字operator關(guān)鍵字重寫包括:+,-,*,/,<,>,<=,>=,%,/,[],[]=,,=,<<,>>等十幾種運算符:
類型自動推斷
在聲明一個變量時,無需指定類型,系統(tǒng)會自動推斷,比如var m= {"a":1};var i=1;
,系統(tǒng)自動認為m
是Map類型
,i
是整型
。如果一個變量被賦值后,在后續(xù)會被另外類型的變量值覆寫,應(yīng)該使用dynamic
聲明這個變量。
final和const
用來定義常量,都必須初始化,const
是編譯時常量,只能用編譯時常量來初始化,但final
可以用變量來初始化,比如final time = new DateTime.now();
是允許的。
函數(shù)
函數(shù)類型是Function,函數(shù)可以賦值,也可以作為參數(shù)傳遞給其他函數(shù),這是函數(shù)式編程典型特征。在Dart中不能重載函數(shù),函數(shù)可以不指定返回類型(實際會返回Object),而實際上函數(shù)體可以返回任意類型,如果在函數(shù)體中沒有return,則返回null。
在我們編寫Flutter程序時,經(jīng)常會碰到函數(shù)體只是返回一個布局,那么函數(shù)體在一條語句的情況下,可以簡寫成:void printxx(num n) => print(n);
,注意箭頭的用法。
另外函數(shù)的參數(shù)非常有意思,可指定可選參數(shù)(使用{}將可選參數(shù)括起來),可以通過:或=指定參數(shù)默認值,也可以使用位置參數(shù)(用[]括起來),注意位置參數(shù)如果有多個,必須跟實際傳入的是實參一一對應(yīng)。
函數(shù)可以用來賦值,比如:var uu = (msg) => "'${msg.toUpperCase()}'";
,以上uu是一個函數(shù),將傳入的字符串轉(zhuǎn)換成大寫,可以直接調(diào)用uu("hello")
即返回HELLO
。
函數(shù)也可以作為參數(shù),比如Future.delayed(new Duration(seconds: 2),(){return "hi";})
,第二個參數(shù)就是一個函數(shù),函數(shù)作為參數(shù)的用法在Flutter編程中隨處可見,是一個非常重要的用法。
構(gòu)造函數(shù)
Dart是不支持函數(shù)重載的,那多個構(gòu)造函數(shù)怎么辦?我們可以使用命名構(gòu)造函數(shù),比如Text.a(this.a);Test.ab(this.a,this.b)
等命令構(gòu)造函數(shù)
閉包
一個閉包是一個方法對象,不管該對象在何處被調(diào)用, 該對象都可以訪問其作用域內(nèi)的變量。方法可以封閉定義到其作用域內(nèi)的變量。比如以下代碼:
Function makeAdder(num addBy) {
return (num i) => addBy + i;
}
main() {
var add2 = makeAdder(2);
var add4 = makeAdder(4);
assert(add2(3) == 5);
assert(add4(3) == 7);
}
異步支持
Dart類庫有非常多的返回Future或者Stream對象的函數(shù)。 這些函數(shù)被稱為異步函數(shù)。async和await關(guān)鍵詞支持了異步編程,允許您寫出和同步代碼很像的異步代碼。
以上寫法在Flutter編程中經(jīng)常被用到,將異步的調(diào)用方式以同步的寫法呈現(xiàn),使得我們理解起來更加直觀。
元數(shù)據(jù)注解
元數(shù)據(jù)注解以字符開頭@
,后跟對編譯時常量(如deprecated
)的引用或?qū)ΤA繕?gòu)造函數(shù)的調(diào)用。元數(shù)據(jù)可以出現(xiàn)在庫
,類
,typedef
,類型參數(shù)
,構(gòu)造函數(shù)
,工廠
,函數(shù)
,字段
,參數(shù)
或變量聲明之前以及導(dǎo)入或?qū)С鲋噶钪啊D梢允褂梅瓷湓谶\行時檢索元數(shù)據(jù),所有Dart代碼都有兩個注解:@deprecated
和 @override
。你可以定義自己的元數(shù)據(jù)注解,如下:
之后就可以使用注解:
@todo('name','ddd')
。
Mixin
有時候?qū)⒛承┬袨槎x為Mixin,以便讓其他類通過with來實現(xiàn)多重繼承,減少代碼冗余。比如var CC=T with A,B
,表示CC類中的方法是T,A,B三個類的方法的并集,當(dāng)有函數(shù)名重名的時候,B的方法覆蓋A,T的,A方法覆蓋T的。這樣就變相支持了多重繼承。
反射
dart:mirrors 庫提供了基本的反射支持。可以通過#打頭定義Symbols,這樣在代碼混交的情況下也可以保持標識符名稱。比如你知道類名,可以直接用new Symbol("CLASSNAME")來構(gòu)建symbol。比如我們動態(tài)調(diào)用C類的d方法,d方法有一個參數(shù):
class C{
var tt = "test";
C(){};
static d(msg){print(msg);}
a(){print("C.a";)}
}
//調(diào)用類的靜態(tài)函數(shù)
ClassMirror cc = reflectClass(C);
cc.invoke(Symbol("d"), ["hello"]);
//如果調(diào)用實例函數(shù)
InstanceMirror mm = cc.newInstance(Symbol.empty, []);
mm.invoke(Symbol("a"), []);
//獲取類的成員變量
print(mm.reflectee.tt);
此外,還可以通過反射獲取注解,元數(shù)據(jù)等,具體可參考:http://www.lxweimin.com/p/d68278d19f79
Flutter中禁止使用反射。