[Swift]Day13:協議,swiftday13協議
協議屬性協議
我們可以在協議中定義屬性,下面的代碼就是錯誤的,因為協議中定義了唯讀屬性,但是卻嘗試修改其值:
protocol FullyNamed { var fullName: String { get }}struct Person: FullyNamed{ var fullName: String}let john = Person(fullName: "WHY")john.fullName = "WHY" // ERROR!協議合成
一個協議可由多個協議採用 protocol<SomeProtocol, AnotherProtocol> 這樣的格式進行組合,稱為協議合成(protocol composition)。
protocol Named { var name: String { get }}protocol Aged { var age: Int { get }}struct Person: Named, Aged { var name: String var age: Int}func wishHappyBirthday(celebrator: protocol<Named, Aged>) { println("Happy birthday \(celebrator.name) - you're \(celebrator.age)!")}let birthdayPerson = Person(name: "Malcolm", age: 21)wishHappyBirthday(birthdayPerson)協議實戰
我們來設計一個計數器,實戰練習一下協議相關的內容。
首先先定義一個協議,CounterDataSource ,這個協議提供了增量值,也就是說,計數器每次計數增加的數值。這個值可以是一個固定值,比如每次增一,也可以是個方法,根據不同情況返回不同的增量值。所以我們的定義如下:
@objc protocol CounterDataSource { optional func incrementForCount(count: Int) -> Int optional var fixedIncrement: Int { get }}
@objc 表示協議是可選的,也可以用來表示暴露給Objective-C的代碼,只對類有效。
接下來我們來定義一個計數器,這個計數器裡有一個 CounterDataSource 類型的資料來源。有點像是UITableViewDataSource 的感覺,我們通過這個協議來擷取這一次計數增加的步長。如果 dataSource 實現了incrementForCount 方法,那麼就通過這個方法來擷取步長,否則看看能不能通過固定值擷取步長:
@objc class Counter { var count = 0 var dataSource: CounterDataSource? func increment() { if let amount = dataSource?.incrementForCount?(count) { count += amount } else if let amount = dataSource?.fixedIncrement? { count += amount } }}
可以先用固定值的方法計數:
class ThreeSource: CounterDataSource { let fixedIncrement = 3}var counter = Counter()counter.dataSource = ThreeSource()for _ in 1...4 { counter.increment() println(counter.count)}// 3// 6// 9// 12
也可以用方法來計數:
class TowardsZeroSource: CounterDataSource {func incrementForCount(count: Int) -> Int { if count == 0 { return 0 } else if count < 0 { return 1 } else { return -1 } }}counter.count = -4counter.dataSource = TowardsZeroSource()for _ in 1...5 { counter.increment() println(counter.count)}// -3// -2// -1// 0// 0
最近時間有限,簡單閱讀了一下官方文檔。以後遇到了再補充吧。
References