你可以使⽤《型別轉換》中描述的 is 和 as 操作符來檢查協議一致性,即是否符合某協議,並且可以轉換到指定的協議型別。檢
查和轉換協議的語法與檢查和轉換型別是完全一樣的:
1. is 用來檢查實例是否符合某個協議,若符合則返回 true ,否則返回 false ;
2. as? 返回乙個可選值,當實例符合某個協議時,返回型別為協議型別的可選值,否則返回 nil ;
3. as! 將實例強制向下轉換到某個協議型別,如果強轉失敗,將觸發運⾏時錯誤。
下面的例子定義了乙個 hasarea 協議,該協議定義了乙個 double 型別的可讀屬性 area :
protocol hasarea
如下所示, circle 類和 country 類都遵循了 hasarea 協議:
class circle: hasarea
init(radius: double)
circle 類把 area 屬性實現為基於儲存型屬性 radius 的計算型屬性。 country 類則把 area 屬性實現為儲存型屬性。這兩個類都正
確地遵循了 hasarea 協議。
如下所示, animal 是乙個未遵循 hasarea 協議的類:
class animal
circle , country , animal 並沒有乙個共同的基類,儘管如此,它們都是類,它們的實例都可以作為anyobject 型別的值,儲存
在同乙個陣列中:
let objects: [anyobject] = [
circle(radius: 2.0),
country(area: 243_610),
animal(legs: 4)
objects 陣列使用字面量初始化,陣列包含乙個 radius 為 2 的 circle 的實例,乙個儲存了英國土面積的 country 實例和乙個 legs
為 4 的 animal 實例。
如下所示, objects 陣列可以被迭代,並對迭代出的每乙個元素進⾏檢查,看它是否符合 hasarea 協議:
for object in objects else
counterdatasource 協議定義了乙個可選方法 increment(forcount:) 和乙個可選屬性 fiexdincrement ,它們使用了不同的方法來
從資料來源中獲取適當的增量值。
嚴格來講, counterdatasource 協議中的方法和屬性都是可選的,因此遵循協議的類可以不實現這些要求,儘管技術上允許這樣
做,不過最好不要這樣寫。
counter 類含有 counterdatasource? 型別的可選屬性 datasource ,如下所示:
class counter else if let amount = datasource?.fixedincrement
// 3
// 6
// 9
// 12
上述**新建了乙個 counter 實例,並將它的資料來源設定為乙個 threesource 的實例,然後呼叫 increment()方法 4 次。按照預期一樣,每次呼叫都會將 count 的值增加 3 .
下⾯是乙個更為複雜的資料來源 towardszerosource ,它將使得最後的值變為 0 :
class towardszerosource: nsobject, counterdatasource else if count < 0 else
// -3
// -2
// -1
// 0
// 0
協議可以通過擴充套件來為遵循協議的型別提供屬性、方法以及下標的實現。通過這種方式,你可以基於協議本身來實現這些功能,⽽
無需在每個遵循協議的型別中都重複同樣的實現,也⽆需使用全域性函式。
例如,可以擴充套件 randomnumbergenerator 協議來提供 randombool() ⽅法。該方法使用協議中定義的 random()方法來返回乙個
隨機的 bool 值:
extension randomnumbergenerator
通過協議擴充套件,所有遵循協議的型別,都能自動獲得這個擴充套件所增加的方法實現而無需任何額外修改:
let generator = linearcongruentialgenerator()
print("here's a random number: \(generator.random())")
// 列印 「here's a random number: 0.37464991998171」
print("and here's a random boolean: \(generator.randombool())")
// 列印 「and here's a random boolean: true」
可以通過協議擴充套件來為協議要求的屬性、方法以及下標提供預設的實現。如果遵循協議的型別為這些要求提供了⾃己的實現,那
麼這些自定義實現將會替代擴充套件中的預設實現被使用。
通過協議擴充套件為協議要求提供的預設實現和可選的協議要求不同。雖然在這兩種情況下,遵循協議的型別都無需自己實現這些要
求,但是通過擴充套件提供的預設實現可以直接呼叫,⽽無需使用可選鏈式呼叫。
例如, prettytextrepresentable 協議繼承自 textrepresentable 協議,可以為其提供乙個預設的 prettytextualdescription 屬性
來簡單地返回 textualdescription 屬性的值:
extension prettytextrepresentable
}
在擴充套件協議的時候,可以指定一些限制條件,只有遵循協議的型別滿足這些限制條件時,才能獲得協議擴充套件提供的預設實現。這
些限制條件寫在協議名之後,使用 where 子句來描述,正如《泛型 where ⼦句》中所描述的。
例如,你可以擴充套件 collection 協議,適用於集合中的元素遵循了 equatable 協議的情況。通過限制集合元素遵 equatable 協議,
作為標準庫的一部分, 你可以使用 == 和 != 操作符來檢查兩個元素的等價性和非等價性。
extension collection where element: equatable
return true
如果集合中的所有元素都一致, allequal() 方法才返回 true 。 看看兩個整數陣列,乙個陣列的所有元素都是一樣的,另乙個不一
樣:let equalnumbers = [100, 100, 100, 100, 100]
let differentnumbers = [100, 100, 200, 100, 200]
由於陣列遵循 collection 而且整數遵循 equatable , equalnumbers 和 differentnumbers 都可以使用allequal() 方法。
print(equalnumbers.allequal())
// 列印 "true"
print(differentnumbers.allequal())
// 列印 "false"
如果乙個遵循的型別滿⾜了為同一方法或屬性提供實現的多個限制型擴充套件的要求, swift 會使用最匹配限制的實現。
CUDA學習(三十三)
最大化指令吞吐量 為了最大化指令吞吐量,應用程式應 在本節中,吞吐量以每個多處理器每個時鐘週期的操作次數給出。對於32的變形大小,一條指令對應於32個操作,所以如果n是每個時鐘週期的運算元,則指令吞吐量是每個時鐘週期n 32條指令。所有的吞吐量都是針對乙個多處理器的。它們必須乘以裝置中的多處理器數量...
學習總結 三十三
1 什麼是守護程序 程序是乙個正在執行的程式,守護程序也是乙個程序,守護程序的意思就是乙個程序保護另乙個程序 2 守護程序使用場景 1 什麼是互斥鎖 互斥鎖就是互相排斥的鎖,乙個資源被鎖了,其他子程序就無法使用 2 為什麼需要互斥鎖 因為併發帶來的資源競爭問題,當多個程序同時要操作乙個資源將會導致資...
Python學習之旅(三十三)
網路通訊是兩台計算機上的兩個程序之間的通訊,而網路程式設計就是如何在程式中實現兩台計算機的通訊 p協議負責把資料從一台計算機通過網路傳送到另一台計算機 tcp協議則是建立在ip協議之上的。tcp協議負責在兩台計算機之間建立可靠連線,保證資料報按順序到達 許多常用的更高階的協議都是建立在tcp協議基礎...