標籤:tle 遇到 span bar ror 體會 origin https 位置
Typealiastypealias 是用來為已經存在的類型重新定義名字的,通過命名,可以使代碼變得更加清晰。使用的文法也很簡單,使用typealias 關鍵字像使用普通的指派陳述式一樣,可以將某個已經存在的類型賦值為新的名字。比如在計算二維平面上的距離和位置的時候,我們一般使用Double來表示距離,用CGPoint來表示位置:
[javascript] view plain copy
- func distance(_ point: CGPoint, _ anotherPoint: CGPoint) -> Double {
- let dx = Double(anotherPoint.x - point.x)
- let dy = Double(anotherPoint.y - point.y)
- return sqrt(dx * dx + dy * dy)
- }
-
- let origin = CGPoint(x: 3, y: 0)
- let point = CGPoint(x: 4, y: 0)
-
- let d = distance(origin, point)
雖然在數學上和最後的程式運行上都沒什麼問題,但是閱讀和維護的時候總是覺得有哪裡不對。 因為我們沒有將數學抽象和實際問題結合起來,使得在閱讀代碼時我們還需要在大腦中進行一次額外的轉換:CGPoint代表一個點,而這個點就是我們在定義的座標系裡的位置; Double是一個 數字,它代表兩個點之間的距離。 如果我們使用 typealias,就可以將這種轉換直接寫在代碼裡,從而減輕閱讀和維護的負擔:
[javascript] view plain copy
- func distance(_ point: CGPoint, _ anotherPoint: CGPoint) -> Double {
- let dx = Distance(anotherPoint.x - point.x)
- let dy = Distance(anotherPoint.y - point.y)
- return sqrt(dx * dx + dy * dy)
- }
-
- let origin = Location(x: 3, y: 0)
- let point = Location(x: 4, y: 0)
-
- let d = distance(origin, point)
同樣的代碼,在 typealias 的協助下,讀起來就輕鬆多了。可能單單這個簡單例子不會有特別多的 體會,但是當你遇到更複雜的實際問題時,你就可以不再關心並去思考自己代碼裡那些成堆的Int或者String之類的基本類型到底代表的是什麼東西了,這樣你應該能省下不少腦細胞。注意:開發過程中,當使用的比包的使用,會經常使用typealias
[javascript] view plain copy
- typealias Success = (_ data: String) -> Void
- typealias Failure = (_ error: String) -> Void
-
- func request(_ url: String, success: Success, failure: Failure) {
- // do request here ....
- }
typealias與泛型typealias 是單一的,也就是說你必須指定將某個特定的類型通過typealias賦值為新名字,而不能將整個泛型型別進行重新命名。下面這樣的命名都是無法通過編譯的:
[javascript] view plain copy
- class Person<T> {}
- typealias Woker = Person
- typealias Worker = Person<T>
不過如果我們在別名中也引入泛型,是可以進行對應的
[javascript] view plain copy
- class Person<T> {}
- typealias Woker = Person
- typealias Worker<T> = Person<T>
當泛型型別的確定性得到保證後,顯然別名也是可以使用的:
[javascript] view plain copy
- class Person<T> {}
- typealias WorkId = String
- typealias Worker = Person<WorkId>
另一個使用情境是某個類型同時實現多個協議的組合時。我們可以使用&符號串連幾個協議,然後給它們一個新的更符合內容相關的名字,來增強代碼可讀性:
[javascript] view plain copy
- protocol Cat {}
- protocol Dog {}
- typealias Pat = Cat & Dog
associatedtype關聯類別型 定義一個協議時,有的時候聲明一個或多個關聯類別型作為協議定義的一部分將會非常有用。關聯類別型為協議中的某個類型提供了一個佔位名(或者說別名),其代表的實際類型在協議被採納時才會被指定。你可以通過 associatedtype 關鍵字來指定關聯類別型。比如使用協議聲明更新cell的方法:
[javascript] view plain copy
- //模型
- struct Model {
- let age: Int
- }
-
- //協議,使用關聯類別型
- protocol TableViewCell {
- associatedtype T
- func updateCell(_ data: T)
- }
-
- //遵守TableViewCell
- class MyTableViewCell: UITableViewCell, TableViewCell {
- typealias T = Model
- func updateCell(_ data: Model) {
- // do something ...
- }
- }
Swift - 關鍵字(typealias、associatedtype)