1. 程式人生 > >Swift - 關鍵字(typealias、associatedtype)

Swift - 關鍵字(typealias、associatedtype)

cell 是什麽 eth ucc 定義 truct 幫助 rip too

Typealias

typealias 是用來為已經存在的類型重新定義名字的,通過命名,可以使代碼變得更加清晰。使用的語法也很簡單,使用typealias 關鍵字像使用普通的賦值語句一樣,可以將某個已經存在的類型賦值為新的名字。比如在計算二維平面上的距離和位置的時候,我們一般使用Double來表示距離,用CGPoint來表示位置:

[javascript] view plain copy
  1. func distance(_ point: CGPoint, _ anotherPoint: CGPoint) -> Double {
  2. let dx = Double(anotherPoint.x - point.x)
  3. let dy = Double(anotherPoint.y - point.y)
  4. return sqrt(dx * dx + dy * dy)
  5. }
  6. let origin = CGPoint(x: 3, y: 0)
  7. let point = CGPoint(x: 4, y: 0)
  8. let d = distance(origin, point)
雖然在數學上和最後的程序運行上都沒什麽問題,但是閱讀和維護的時候總是覺得有哪裏不對。 因為我們沒有將數學抽象和實際問題結合起來,使得在閱讀代碼時我們還需要在大腦中進行一次額外的轉換:CGPoint代表一個點,而這個點就是我們在定義的坐標系裏的位置; Double是一個 數字,它代表兩個點之間的距離。 如果我們使用 typealias,就可以將這種轉換直接寫在代碼裏,從而減輕閱讀和維護的負擔:

[javascript] view plain copy
  1. func distance(_ point: CGPoint, _ anotherPoint: CGPoint) -> Double {
  2. let dx = Distance(anotherPoint.x - point.x)
  3. let dy = Distance(anotherPoint.y - point.y)
  4. return sqrt(dx * dx + dy * dy)
  5. }
  6. let origin = Location(x: 3, y: 0)
  7. let point = Location(x: 4, y: 0)
  8. let d = distance(origin, point)
同樣的代碼,在 typealias 的幫助下,讀起來就輕松多了。可能單單這個簡單例子不會有特別多的 體會,但是當你遇到更復雜的實際問題時,你就可以不再關心並去思考自己代碼裏那些成堆的Int或者String之類的基本類型到底代表的是什麽東西了,這樣你應該能省下不少腦細胞。註意:開發過程中,當使用的比包的使用,會經常使用typealias

[javascript] view plain copy
  1. typealias Success = (_ data: String) -> Void
  2. typealias Failure = (_ error: String) -> Void
  3. func request(_ url: String, success: Success, failure: Failure) {
  4. // do request here ....
  5. }

typealias與泛型

typealias 是單一的,也就是說你必須指定將某個特定的類型通過typealias賦值為新名字,而不能將整個泛型類型進行重命名。下面這樣的命名都是無法通過編譯的:

[javascript] view plain copy
  1. class Person<T> {}
  2. typealias Woker = Person
  3. typealias Worker = Person<T>
不過如果我們在別名中也引入泛型,是可以進行對應的 [javascript] view plain copy
  1. class Person<T> {}
  2. typealias Woker = Person
  3. typealias Worker<T> = Person<T>
當泛型類型的確定性得到保證後,顯然別名也是可以使用的:

[javascript] view plain copy
  1. class Person<T> {}
  2. typealias WorkId = String
  3. typealias Worker = Person<WorkId>
另一個使用場景是某個類型同時實現多個協議的組合時。我們可以使用&符號連接幾個協議,然後給它們一個新的更符合上下文的名字,來增強代碼可讀性:

[javascript] view plain copy
  1. protocol Cat {}
  2. protocol Dog {}
  3. typealias Pat = Cat & Dog

associatedtype關聯類型

定義一個協議時,有的時候聲明一個或多個關聯類型作為協議定義的一部分將會非常有用。關聯類型為協議中的某個類型提供了一個占位名(或者說別名),其代表的實際類型在協議被采納時才會被指定。你可以通過 associatedtype 關鍵字來指定關聯類型。比如使用協議聲明更新cell的方法:

[javascript] view plain copy
  1. //模型
  2. struct Model {
  3. let age: Int
  4. }
  5. //協議,使用關聯類型
  6. protocol TableViewCell {
  7. associatedtype T
  8. func updateCell(_ data: T)
  9. }
  10. //遵守TableViewCell
  11. class MyTableViewCell: UITableViewCell, TableViewCell {
  12. typealias T = Model
  13. func updateCell(_ data: Model) {
  14. // do something ...
  15. }
  16. }

Swift - 關鍵字(typealias、associatedtype)