此篇內(nèi)容均來源于《Dart編程語言》--[美]Gilad Bracha 著 戴虬 譯
設(shè)計(jì)準(zhǔn)則
1.1 萬物皆對象
dart是一門由google開發(fā)并被批準(zhǔn)為ECMA標(biāo)準(zhǔn)(ECMA-408)的通用編程語言挖藏。它可以用于構(gòu)建web端颜武、服務(wù)端和移動端應(yīng)用程序轧邪。它是開源的,使用寬松的免費(fèi)軟件許可證(修改版BSD許可證)腕窥。Dart是完全面向?qū)ο蟮模褂妙惡蛦卫^承筛婉,可編譯為JavaScript簇爆,語法風(fēng)格是類C的。它支持接口爽撒、mixin入蛆、抽象類、泛型和可選類型硕勿。
Dart是一門純面向?qū)ο蟮木幊陶Z言哨毁,這意味著Dart程序在運(yùn)行時(shí)所處理的值都是對象,甚至包括數(shù)字源武,布爾值等基本數(shù)據(jù)扼褪,無一例外想幻。
Dart堅(jiān)持對所有數(shù)據(jù)統(tǒng)一處理,這方便了所有與語言相關(guān)的人員:語言的設(shè)計(jì)者话浇,實(shí)現(xiàn)者脏毯,以及最重要的使用者。
1.2 面向接口編程幔崖,而非面向?qū)崿F(xiàn)
關(guān)注對象的行為而非他的內(nèi)部實(shí)現(xiàn)食店,這是面向?qū)ο缶幊陶Z言的核心原則。雖然實(shí)現(xiàn)的不夠完美赏寇,Dart卻力圖通過以下幾種方式來維護(hù)這個原則叛买。
- Dart的類型基于接口,而不是類蹋订。作為一項(xiàng)原則率挣,任意類都隱含了一個接口,能夠被其它類實(shí)現(xiàn)露戒,不管其他類是否使用了同樣的底層實(shí)現(xiàn)(部分core type例外椒功,比如數(shù)字,布爾值與字符串)
- Dart沒有final方法智什,允許重寫幾乎所有方法(同樣动漾,部分內(nèi)置的操作符例外)。
- Dart把對象進(jìn)行了抽象封裝荠锭,確保所有外部操作都通過存取方法來改變對象的狀態(tài)
- Dart的構(gòu)造函數(shù)允許對對象進(jìn)行緩存旱眯,或者從子類型創(chuàng)建實(shí)例,因此使用構(gòu)造函數(shù)并不意味著綁定了一個具體的實(shí)現(xiàn)证九。
1.3 類型可選
- 類型在語法層面上來說是可選的
- 類型對運(yùn)行時(shí)語義沒有影響
類型可選照顧了那些不愿意與類型系統(tǒng)打交道的開發(fā)者删豺。因此而選擇Dart的開發(fā)者,完全可以把Dart當(dāng)成一門動態(tài)類型語言愧怜。雖然類型可選呀页,但只要代碼中有類型注解,就意味著代碼有了額外的文檔拥坛,所有的編碼人員都會從中受益蓬蝶。類型注解同時(shí)讓工具能更好的配合開發(fā)者的開發(fā)工作。
對于可能存在的類型不一致和遺漏猜惋,Dart會給出警告丸氛,不會報(bào)錯。這些警告的程度和性質(zhì)都經(jīng)過校準(zhǔn)著摔,不會鋪天蓋地的出現(xiàn)缓窜,確保真正對開發(fā)者有益。同時(shí),Dart編譯器不會拒絕一段缺少類型或類型不一致的程序雹洗。
概述
2.1最簡單的表達(dá)式
3
這個表達(dá)式的值是整數(shù)3.
mymain(){
print("hello world");
print(3);
print(3+4);
print((3+4)*6);
print(1+2*2);
print(1234567890987654321*1234567890987654321);
}
結(jié)果:
hello world
3
7
42
5
6172041164457194081
Exited
最后一個例子比較有趣香罐, 書上的結(jié)果是1524157877457704723228166437789971041.Dart中的整數(shù)很像數(shù)學(xué)里的數(shù)字,他們沒有32位或64位可代表的最大值的限制时肿,其大小的唯一限制是可用內(nèi)存庇茫。
Dart不僅支持整數(shù),也支持浮點(diǎn)數(shù)螃成,字符串旦签,布爾值,許多內(nèi)置類型都有很簡便的語法
dataType() {
3.14159; // 一個浮點(diǎn)數(shù)
'a string';
true;
false; //布爾值
[]; //一個空列表
[
0,
1.0,
false,
'a',
[2, 2.0, true, "b"]
]; // 有5個元素的列表 寸宏,最后一個也是列表宁炫。
}
Dart的列表相當(dāng)于其他語言的數(shù)組,Dart是用List來表示數(shù)組的氮凝。
list(){
print([1,2,3].length);// 3
print([].length);// 0
print([].isEmpty); // true
print(['a'].isNotEmpty);// true
}
2.2 函數(shù)
一個Dart程序的執(zhí)行總是開始于對main() 函數(shù)的調(diào)用羔巢。每個函數(shù)都由函數(shù)頭與函數(shù)體組成。函數(shù)的頭部定義了函數(shù)的名稱與參數(shù)罩阵。
twice(x) => x * 2;
聲明了一個名為twice的函數(shù)竿秆,并有一個名為x的參數(shù)。該函數(shù)返回x乘以2的結(jié)果稿壁。我們可以這樣來執(zhí)行它
twice(2); // 4
以上函數(shù)調(diào)用的結(jié)果是4.這個twice函數(shù)有兩部分幽钢,一部分是由函數(shù)名與形式參數(shù)組成的函數(shù)簽名,另一部分就是跟在=>后面的只包含了一個表達(dá)式的函數(shù)體傅是。另一種更傳統(tǒng)的書寫方式是:
twice(x) {
return x * 2;
}
另一個函數(shù)
// 使用了if語句
max(x, y) {
if (x > y)
return x;
else
return y;
}
可以簡寫成
// 使用條件表達(dá)式
max(x, y) => (x > y) ? x : y;
另一個更加復(fù)雜的函數(shù)
maxElement(a) {// 接收一個列表a匪燕,并返回一個最大值
var currentMax =// 聲明一個currentMax變量,并對其進(jìn)行初始化(Dart程序中每個變量必須顯示聲明)
a.isEmpty ? throw 'Maximal element undefined for empty arrray' : a[0];
// 異常是使用throw語句拋出的喧笔。throw關(guān)鍵字后面跟著一個定義拋出內(nèi)容的表達(dá)式帽驯。在Dart中,
// 任何類型值都可以被拋出溃斋,不要求他們是特定的Exception類型界拦。
for (var i = 0; i < a.length; i++) {
currentMax = max(a[i], currentMax);
}
return currentMax;
}
2.3 類
Dart允許你在類外部定義函數(shù)與變量。雖然如此梗劫,Dart是一門純面向?qū)ο蟮恼Z言。我們前面看到的所有值截碴,包括數(shù)字梳侨, 字符串,布爾值日丹,列表甚至函數(shù)本身都是Dart中的對象走哺。所有這些對象都是某個類的實(shí)例。像length哲虾,isEmpty這些操作丙躏, 甚至[]索引操作符择示,都是對象的方法。
現(xiàn)在我們學(xué)習(xí)如何編寫一個類晒旅。請看這個Point類栅盲,它代表了直角坐標(biāo)系的點(diǎn):
class Point {
var x, y;
Point(a, b) {
x = a;
y = b;
}
}
要創(chuàng)建一個Point類的實(shí)例,我們可以用new表達(dá)式來調(diào)用它的構(gòu)造函數(shù):
var origin = new Point(0, 0);
var aPoint = new Point(3, 4);
var anotherPoint = new Point(3, 4);
以上3行創(chuàng)建了3個新的不一樣的Point實(shí)例废恋,特別是谈秫,aPoint和anotherPoint是兩個不同的對象。每個對象都有唯一標(biāo)識鱼鼓,他們通過這個標(biāo)識來區(qū)分彼此拟烫。
每個Point的實(shí)例都有各自的x和y變量的副本,可以通過點(diǎn)符號來訪問他們:
printPoint(){
print(origin.x);
print(origin.y);
print(aPoint.x);
print(aPoint.y);
print(anotherPoint.x);
print(anotherPoint.y);
}
結(jié)果如下:
0
0
3
4
3
4
變量x和y的值是由構(gòu)造函數(shù)的實(shí)際參數(shù)來設(shè)置的迄本,而構(gòu)造函數(shù)是由new調(diào)用的硕淑。將構(gòu)造函數(shù)的形式參數(shù)直接賦值給同名的字段,這種方式非常普遍嘉赎,所以Dart為此提供了一種特殊的語法糖:
class Point{
var x, y;
Point(this.x, this.y);
}
新版的Point與原版完全相同置媳,但更簡潔。我們再給它添加一些行為:
class Point{
var x, y;
Point(this.x, this.y);
scale(factor) => new Point(x * factor, y * factor);
}
這個版本多一個scale方法曹阔,它接收一個定義比例系數(shù)的參數(shù)factor半开,并返回一個新的點(diǎn)。新的點(diǎn)的坐標(biāo)是根據(jù)當(dāng)前點(diǎn)的坐標(biāo)按照facor縮放而得來的赃份。
print(aPoint.scale(2).x); // 6
print(anotherPoint.scale(3).y); // 12
另外一個有趣的操作就是對點(diǎn)進(jìn)行加法操作:
class Point{
var x, y;
Point(this.x, this.y);
scale(factor) => new Point(x * factor, y * factor);
operator + (p) => new Point(x + p.x, y + p.y);
}
結(jié)果:
print((aPoint + anotherPoint).y);// 8
2.4 靜態(tài)成員
Dart也支持靜態(tài)成員寂拆。我們可以給Point添加一個計(jì)算兩點(diǎn)間距離的靜態(tài)方法
static distance(p1, p2) {
var dx = p1.x - p2.x;
var dy = p1.y - p2.y;
return sqrt(dx * dx + dy * dy);
}
static修飾符表明此方法不針對某個特定實(shí)例,它無法訪問實(shí)例變量x和y抓韩,因?yàn)閷?shí)例變量對于每個Point實(shí)例都是不同的纠永。
Dart代碼用庫作為模塊化的基本單元。每個庫都定義了一個的命名空間谒拴,這個命名空間包含所有在庫中聲明的實(shí)體的名稱尝江,其他庫的實(shí)體也能被導(dǎo)入進(jìn)來。Dart核心庫中聲明的實(shí)體英上,都會被隱含的導(dǎo)入到所有的Dart庫中炭序。
import 'dart:math';
class Point {
var x, y;
Point(this.x, this.y);
scale(factor) => new Point(x * factor, y * factor);
operator +(p) => new Point(x + p.x, y + p.y);
static distance(p1, p2) {
var dx = p1.x - p2.x;
var dy = p1.y - p2.y;
return sqrt(dx * dx + dy * dy);
}
}