Swift55個協議的分類和講解分析

2022-08-30 08:51:16 字數 4585 閱讀 5766

首先我只想問:為什麼是協議?為什麼面向協議程式設計?如果我們回到過去那段年少無知少不更事的面相物件程式設計時期,我們很多人最初學習的是objective-c,這意味著我們免受多繼承的專橫。又或者你是這個房間裡另一半喜歡c++的人,那麼我們並沒有受過多繼承的啟示,我們稍後將對其進行討論。

單繼承中,層次結構是線性的:你有父輩、子輩以及孫子輩一系列的繼承樹。當你回到樹的頂端,所有的一切有乙個單獨的父輩。這使得層次乾淨,但同時你的確失去了合理使用多繼承所帶來的優勢。在swift中不能繼承列舉和結構型別,只有類可以。這意味著你有時需要弄得跟麻花一樣來讓你的型別有意義。這樣最終能得到真正通用的超類。然後一級一級下來,如果你可以想象更多的級在你從圖中獲得乙個葉子結點之前,你才能得到乙個真正可以例項化和使用的類。

"你有時需要弄得跟麻花一樣來讓你的型別有意義"

所以通過協議,你可以使得型別系統更加有組合性,你可以理清繼承的長鏈。當然你將要放棄乙個長而高的繼承鏈,為了乙個有協議一致性的寬的鏈。但我認為取捨是值得的,希望在這個演講結束後你也這麼認為。

什麼樣的東西放進協議裡有意義?我不打算談我已經完成的很酷的協議,而是瀏覽一下蘋果在swift標準庫中提供的協議。我們將瀏覽,也許你會學到一些你以前從未聽過的協議。我們究竟能找到什麼偉大的想法,接著也許可以獲得一些靈感——在我們的**裡什麼樣的東西可以和協議一起用。基本上這個演講的思路是swift團隊使用協議的方法,給我們一些可以怎麼用協議的提示?

最終目標是讓你開始思考協議,想出一些很酷的點子然後開源,然後我會在你github的倉庫上點星。

三種協議類別:"can do","is a"以及"can be"

swift標準庫包括54個真正的共有協議。一開始這個演講我開玩笑地想乙個個說明它們,每個16秒來湊時間,但相反,我把它們分成三類。"can do"協議,"is a"協議,"can be"協議。每次我們會看其中乙個,看一些示例,再看看我們能夠學到的東西。

"can do"協議

首先我們先來看看"can do"協議。這些描述的事情是型別可以做或已經做過的,它們也以 -able 結尾為語法,這使得當你瀏覽標頭檔案時它們很容易被找到。第乙個例子:乙個型別遵守hashable協議,意味著你可以得到這個類的整型雜湊值。這意味著你可以把它儲存進乙個集合,可以當作乙個字典的鍵等等。還有equatable和comparable協議,這意味著你可以用swift中各種相等和比較的運算子比較兩個例項的值。這些都是很常見的協議,你可能已經在你自己的型別中實現了。你會注意到這些協議描述了你可以對類進行的操作。有比較、相等、雜湊。

"absolutevaluable(絕對有價值)。這聽起來如此重要。正因為它以'valuable(價值)'結尾"

這裡做乙個補充說明,讓我們來談談我認為的最好的命名協議,它值得乙個特殊的過度動畫:absolutevaluable(絕對有價值)。這聽起來如此重要。正因為它以"valuable(價值)"結尾。但不幸的是它沒有聽起來那麼重要。它只意味著支援絕對值函式。

還有乙個小協議子集在這個"can do"組中,和替代檢視或替代表示形式有關。

讓我們看看乙個簡單的例子rawrepresentable。這意味著該類可以表示成某種原始值,然後你可以把原始值轉變回實際的例項。這聽起來很像swift裡的列舉,有內建的原始值。所以所有有列舉的功能的類有乙個初始化函式,它接受乙個原始值,一旦你有乙個列舉值就得到它原始值的版本。這些都建立在這個協議之上。你可以用自己的結構體和類做類似的事情,如果你喜歡。這裡的想法是,東西內在的值是一樣的,你只是改變它外在的表示。只因為,原始值和例項值之間存在一對一的對映。

同屬此類。

接下來是customplaygroundquicklookable。這只是意味著你型別可以在playground中快速檢視。同時這也意味著,你的型別是一樣的,你不是將它轉換為其他東西,而是為你的值提供另一種替代檢視。在這種情況下,它可以在快速瀏覽中顯示。

"所以我們有操作,我們有替代試圖。從中我們可以學到什麼呢?"

替代檢視的例子呢?總存在從大**建立縮圖的情況,你可以認為這是全尺寸**的替代檢視。再次,這實際上不是乙個轉換,它只是替代的表示形式。所以,你可以想象這樣乙個thumbnailable協議,希望你能想出乙個更好的名字,甚至音訊版本的乙個縮圖。縮圖就像乙個低位元率版本的音訊之類的。

"is a"協議

還有一些協議包括的一些原語像integertyp、floatingpointtype、booleantype等等。這些協議更像分組。所以有幾個整數型別。我們有無符號整數、有符號整數、16位整數等等。但它們都組合在一起,因為他們共同遵守整數型別的協議。如果你想出自己的整數型別,也許你想要乙個4位整數或6位整數,有點非主流,那麼為什麼不遵守這個協議。但是,這不大可能發生。大多數這類協議你可能從來沒有編寫型別去遵守這些協議。例如你看booleantype標頭檔案的注釋,實際上勸阻你創造更多的布林型別,因為乙個已足夠。另乙個例子是mirrorpathtype,它的標頭檔案有以下令人愉快的注釋:"不要宣告新的類遵守這個協議,它們不會像預期的那樣工作。」

所以,正如你所看到的,這意味著許多這一類的協議,你可能是使用遵守這些的型別。我相信每個人都使用乙個陣列或乙個整數,但你可能不會建立遵守它們的型別。雖然有一些你可能使用——我們有errortype,我們早些時候聽thomas說過,在swift 2中新的錯誤處理模式用。還有sequencetype、generatortype,如果你正在構建集合化的東西且你想要支援迭代,可以看一看這些協議。

這就是"is a"協議。協議被當作身份。我們可以從這個模式的協議中學到什麼嗎?再次,因為這些都是基於身份而不是操作,你可以在更大的型別分組中使用它們。回到規範化動物王國的例子:這是乙個誇張的很長的類層次結構。底部甚至沒有一種我們可以例項化的型別。在這個類層次結構上,每一步都比之前新增一些功能。因此,有了協議你可以讓你的型別系統有更多的組合性。你有這個協議的清單,你可以構建和在不同型別中使用。比如貓叫和狗吠,更多是一種"can do"風格的動物能做的事,而"兩條腿"和"四條腿"則更多是一種身份型別。你會注意到兩條腿和四條腿也有繼承,因為協議可以像這樣繼承。

這意味著,一旦你設定好了這些協議,你可以建立起過去需要巨大的超類列表而現在只是一組協議的東西,包括繼承如果你需要它。當你構建你的型別,你可以在這裡選擇身份和需要的功能。因為你的型別可以遵守多個協議,你可以一點點建立型別的功能,基於協議的一致性。

這就是第二類的標準庫協議--"is a"協議,與分組和身份有關。

"can be"協議(11.28)

最後我們有"can be"型別。這不是同乙個東西的替代檢視,正如我們已經看到的,這些都是直接轉換。從型別x轉換到y。這些協議以"-convertible"結尾。這意味著這個型別可以被轉換到或者轉換成別的東西。

讓我們看看幾個例子。我們有簡單的初始化風格的,如floatliteralconvertible、integerliteralconvertible、arrayliteralconvertible等等。如果你的型別遵守floatliteralconvertible那麼這意味著你需要乙個初始化函式,接受某種floatliteral,預設情況下這是乙個double值,然後構建你的型別。所以轉換的方向是從乙個浮點數到你的型別。

相比之下,有每個人的最好的朋友customstringconvertible之類的協議,又或如先前知道的printable協議。它指定你的型別可以轉換成乙個字串,所以轉換變到另乙個方向,是從你的型別中到乙個字串。

"乙個objective-c從業者看到,說'啊,那沒什麼。我碼方法宣告的時間比每次我碼**的時間都長。'"

這裡再次補充說明,54個協議中名稱最長的也在此類,extendedgraphemeclusterliteralconvertible——41個字元。我相信那些來自objective-c會說、或笑、就像:"啊,那沒什麼。我碼方法宣告的時間比每次我碼**的時間都長。"這就是用於轉換的協議在這最後一組。我們可以從這樣的協議中學到什麼,除了要盡量保持你型別的名字短?

這麼做的好處是什麼?為什麼需要乙個協議加上轉換函式,而似乎僅僅乙個函式不是更簡單嗎?再次,它一部分是組合的方法。乙個應試者可以成為員工的事實,是型別是什麼的一部分,但這並不特別。其他的人也可以成為員工。通過使用乙個協議可以保證有乙個共同的定義良好的介面來將一些人轉換成乙個員工。

還有乙個好處是,**漂亮的像文件一樣。如果你瀏覽**,或者專案裡的其他人,你會看到"employeeconvertible",並且你已經熟悉它,它告訴了你這型別能做什麼和介面是什麼樣子。你還可以在你的專案查詢"employeeconvertible"這個詞,然後在搜尋結果中,就可以看到能成為員工的型別的列表。這就是"can be"協議組合,處理你型別之間的轉換。

四個廣泛模式

所以我們看到三類來自標準庫的協議,它們與能力、身份和轉換有關。什麼是廣泛的模式,想想我們自己的**?我們有四個:

我想,看到蘋果把如此多的常用功能,如對映、過濾器、列舉函式、抽象到協議,使用的也只是普通的舊協議和協議擴充套件,這是乙個很好的例子。乙個未來將如何強大的靈感。蘋果正遵循這個榜樣。例如,如果你看看陣列的定義,它遵守8個協議,字串遵守12協議,等等。所以這裡的想法是,你建立這些特徵打包在協議裡,然後你的你的**庫就都可以使用。

我認為以這種方式思考你的型別,可以幫助你在腦海裡保持清晰和並把這些型別分類。所以我肯定鼓勵在你自己的**裡嘗試這些。仔細看看你的型別,聚焦於它們的共同點,看能不能用協議。

以上就是我全部要說的。協議萬歲,謝謝!

網路的七個協議

osi是乙個開放性的通訊系統互連參考模型,他是乙個定義得非常好的協議規範。osi模型有7層結構,osi的7層從上到下分別是 7 應用層 6 表示層 5 會話層 4 傳輸層 3 網路層 2 資料鏈路層 1 物理層 其中高層 即7 6 5 4層 定義了應用程式的功能,下面3層 即3 2 1層 主要面向通...

各個協議層的網路請求

應用層的網路請求 用requests庫,來訪問 使用requests庫來訪問 import requests def query name url parameters request requests.get url,params parameters content request.json p...

利用騰訊的乙個協議和「陌生人」聊天

各位在上網聊qq時往往會遇到這樣的情況 你想加的qq號的主人不給你通過驗證,或是一直就沒有反應。這樣,你就無法把他 她 的qq號加到好友裡,也就無法隨意地聊天了。有沒有一種方法,不加對方為好友就能夠向和自己qq號裡的好友一樣的聊天呢?答案是 有。而且方法很簡單,下面就把這種方法介紹給大家。第一步 登...