1. Extensions
擴展指的是對已經(jīng)有的類或者類型添加一些你自己定義的屬性刊侯,方法汁政。甚至對內(nèi)建的類型也可以進行擴展勉躺。這顯然極大的增強了這門語言的威力和靈活性侈百。如下例:
extension Int
{
var a:String{
return "你是個好人"
}
}
var b:Int=2
println(b) //輸出2
println(b.a) //輸出 "你是個好人"
擴展只能添加計算屬性瓮下,不能添加存儲屬性。
你可以給類添加快捷初始化函數(shù)钝域。但是不能給結(jié)構(gòu)體擴展一個委托初始化函數(shù)讽坏。
實例方法的擴展
實例方法的擴展,就是添加一個成員函數(shù)例证。這個成員函數(shù)和被創(chuàng)建的實例綁定路呜。例如:
extension Int
{
func a()->String{
return "你是"+String(self)+"個好人"
}
}
var b:Int=20
println(b) //輸出20
println(b.a()) //輸出“你是20個好人”
如果用mutating關(guān)鍵字,那么實例方法可以修改實例的值织咧。例如:
extension Int
{
mutating func a()
{
self = -self
}
}
var b = 1
println(b) //輸出1
b.a()
println(b) //輸出-1
類型方法的擴展胀葱,前面要加static之類的關(guān)鍵字。這是因為這個方法是和類的定義綁定在一起的笙蒙。例如:
extension Int
{
static func a()
{
println("壞蛋")
}
}
var b = 20
println(b) //輸出20
Int.a() //輸出"壞蛋"
- 下標擴展
你還可以給類型添加下標擴展抵屿,方便使用。下表擴展和方法擴展的寫法非常類似捅位。例如:
extension Int
{
subscript(i:Int)->Int
{
println("下標擴展被調(diào)用")
return 123
}
}
var b = 20
println(b[0]) //輸出“下標擴展被調(diào)用”轧葛;輸出 123
- Protocols
協(xié)議是一組屬性,方法艇搀,下標等的聲明的容器尿扯。當你定義一個類的時候,可以指明它需要遵從的協(xié)議焰雕,然后在類的內(nèi)部姜胖,實現(xiàn)協(xié)議規(guī)定的那些東西。注意淀散,協(xié)議只是個容器右莱,不是實現(xiàn)。所以其實是比類更高一級的描述档插。描述的是多個類的共同特征慢蜓。所以協(xié)議里的變量,只能聲明郭膛,不能初始化晨抡。方法下標也是如此。例如
protocol a {
var ax:Int = 1
} //Playgroudn會立即報錯,"initial value is not allowed here"
了解了協(xié)議這個語法的設(shè)計思路耘柱。它的一些具體寫法和用法就可以自然而然的理解了如捅。
- 協(xié)議定義的格式為:
protocol 協(xié)議名
{//里面寫你要定義的東西
}
- 協(xié)議使用的格式為:
class 類的名字:[上類的名字] 協(xié)議的名字,第二個協(xié)議的名字调煎,..等等
如果一個類是從上類繼承而來镜遣,那么要把上類的名字寫在協(xié)議名字之前。一個類可以遵從多個協(xié)議士袄。
協(xié)議里面的屬性方法等等前面可以加optional 關(guān)鍵字悲关,這用來表示這些元素不一定要在類里面實現(xiàn)。協(xié)議里面的屬性娄柳,后面可以跟{get,set}以表示其為可讀也可寫的屬性寓辱。如果只用get,那就是只需要可讀。如果只用set,那表示只需要可寫赤拒。
除了類之外秫筏,一般的數(shù)據(jù)類型也可以用extension關(guān)鍵字,來使它遵從一個已經(jīng)定義了的協(xié)議挎挖。例如:
protocol a {
func ax()-> Int
}
extension Int: a
{
func ax() -> Int {
println("對不起跳昼,你是個好人")
return 0
}
}
var b = 1
b.ax() //輸出: 對不起,你是個好人
由上例可以看出肋乍,協(xié)議是用于多個類的定義的鹅颊。例如你很多類都要發(fā)好人卡,那么定義個協(xié)議就可以讓你的代碼組織結(jié)構(gòu)更好墓造。如果只是一個類需要這個好人卡函數(shù)堪伍,那就沒必要使用協(xié)議。
面向?qū)ο蟮囊恍┱Z言要素觅闽,到這一章就基本介紹完了帝雇。這里還牽涉到一個更大的話題。一般來說蛉拙,面向?qū)ο蟮暮芏嗵攸c尸闸,例如類繼承擴展協(xié)議等等都是為了更有組織的進行代碼復(fù)用。但是孕锄,每多一層容器吮廉,代碼的冗余部分也就越復(fù)雜,組織結(jié)構(gòu)也就更復(fù)雜畸肆。那么宦芦,到底在設(shè)計項目的結(jié)構(gòu)體系的時候,應(yīng)不應(yīng)該用面向?qū)ο筇匦阅刂崞辏抗P者的意見很簡單:跟著常識走调卑。如果一個對象或者過程抡砂,在現(xiàn)實世界中很容易被擬物,而且后面有很大機會被復(fù)用恬涧,那設(shè)計一個類往往是沒錯的注益。例如圖形界面元素,按鈕溯捆。按鈕本身就是個物體丑搔,然后被圖形界面擬物。按鈕這個物體顯然是有顏色现使,有大小低匙,有被按后進行什么操作的功能的旷痕。所以你設(shè)計個類碳锈,就不會出錯。因為每個程序員腦子里的按鈕都是以現(xiàn)實經(jīng)驗為基礎(chǔ)的欺抗,觀念也就比較一致售碳。
但是,例如一些商業(yè)邏輯绞呈,你采用面向?qū)ο蟮脑O(shè)計思路贸人,就未必是個好辦法。這是因為對商業(yè)邏輯的理解佃声,人人都可能不同艺智。想想看,買火車票排隊這回事圾亏,實際上是多么的復(fù)雜十拣。這種情況下,筆者認為志鹃,不要采用面向?qū)ο蟮姆椒ㄘ参省2蝗辉O(shè)計這個體系結(jié)構(gòu)的人走了,你的項目基本就作廢了曹铃。因為這種情況下設(shè)計出來的類協(xié)議等等缰趋,肯定是個人觀點和視角的產(chǎn)物。而人與人之間的交流陕见,往往比一般人想象的要困難的多秘血。
很多計算機書,拿個什么電話號碼本评甜,什么矩形長寬直撤,什么員工進出紀錄之類的東西,來展示面向?qū)ο蟮姆椒ǘ嗝从杏猛勺牛@實際上是不負責任的做法谋竖。沒有考慮到復(fù)雜體系本身的計算開銷和維護開銷红柱。只考慮了其效果。
當然蓖乘,你要說我有的是錢锤悄。開個項目,寫文檔的也是第一流人才嘉抒,或者文檔的人比寫代碼的素質(zhì)還高零聚。那我就會推薦你用面向?qū)ο蟮脑囟嘁恍?/p>
3. 附錄,GIT為什么是純C寫的些侍?
(
筆者認為隶症,Linus的觀點有些偏頗了。面向?qū)ο缶幊探?jīng)過幾千萬人數(shù)不清程序驗證過的場合岗宣,最牢靠的就是圖形界面設(shè)計蚂会。為什么在這個領(lǐng)域這么牢靠?為什么今天圖形用戶界面部分的編程主流還是面向?qū)ο蟮暮氖剑课艺J為主要原因就是圖形界面都是擬物的胁住。每個人的集體共識都差不多,所以不會出錯刊咳。
)
From: Linus Torvalds <torvalds <at> linux-foundation.org>
Subject: Re: [RFC] Convert builin-mailinfo.c to use The Better String Library.
Newsgroups: gmane.comp.version-control.git
Date: 2007-09-06 17:50:28 GMT (2 years, 14 weeks, 16 hours and 36 minutes ago)
On Wed, 5 Sep 2007, Dmitry Kakurin wrote:
When I first looked at Git source code two things struck me as odd:
- Pure C as opposed to C++. No idea why. Please don't talk about portability,
it's BS.
下面是Linus的回答:
YOU are full of bullshit.
C++ is a horrible language. It's made more horrible by the fact that a lot
of substandard programmers use it, to the point where it's much much
easier to generate total and utter crap with it. Quite frankly, even if
the choice of C were to do nothing but keep the C++ programmers out,
that in itself would be a huge reason to use C.
In other words: the choice of C is the only sane choice. I know Miles
Bader jokingly said "to piss you off", but it's actually true. I've come
to the conclusion that any programmer that would prefer the project to be
in C++ over C is likely a programmer that I really would prefer to piss
off, so that he doesn't come and screw up any project I'm involved with.
C++ leads to really really bad design choices. You invariably start using
the "nice" library features of the language like STL and Boost and other
total and utter crap, that may "help" you program, but causes:
- infinite amounts of pain when they don't work (and anybody who tells me
that STL and especially Boost are stable and portable is just so full
of BS that it's not even funny) - inefficient abstracted programming models where two years down the road
you notice that some abstraction wasn't very efficient, but now all
your code depends on all the nice object models around it, and you
cannot fix it without rewriting your app.
In other words, the only way to do good, efficient, and system-level and
portable C++ ends up to limit yourself to all the things that are
basically available in C. And limiting your project to C means that people
don't screw that up, and also means that you get a lot of programmers that
do actually understand low-level issues and don't screw things up with any
idiotic "object model" crap.
So I'm sorry, but for something like git, where efficiency was a primary
objective, the "advantages" of C++ is just a huge mistake. The fact that
we also piss off people who cannot see that is just a big additional
advantage.
If you want a VCS that is written in C++, go play with Monotone. Really.
They use a "real database". They use "nice object-oriented libraries".
They use "nice C++ abstractions". And quite frankly, as a result of all
these design decisions that sound so appealing to some CS people, the end
result is a horrible and unmaintainable mess.
But I'm sure you'd like it more than git.
Linus