文章目錄:
(1)對(duì)象和類
(2)枚舉和結(jié)構(gòu)體
(3)協(xié)議和擴(kuò)展
(4)泛型
(1)對(duì)象和類
- 要?jiǎng)?chuàng)建一個(gè)類的實(shí)例,在類名后面加上括號(hào)。使用點(diǎn)語法來訪問實(shí)例的屬性和方法。
class Shape {
var numberOfSides = 0
func simpleDescription() -> String {
return "A shape with \(numberOfSides) sides."
}
}
var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()
構(gòu)造函數(shù)來初始化類實(shí)例。使用 init 來創(chuàng)建一個(gè)構(gòu)造器。
如果你需要在刪除對(duì)象之前進(jìn)行一些清理工作,使用 deinit 創(chuàng)建一個(gè)析構(gòu)函數(shù)。
子類的定義方法是在它們的類名后面加上父類的名字,用冒號(hào)分割。創(chuàng)建類的時(shí)候并不需要一個(gè)標(biāo)準(zhǔn)的根類,所以你可以忽略父類。
子類如果要重寫父類的方法的話,需要用 override 標(biāo)記——如果沒有添加 override 就重寫父類方法的話編譯器 會(huì)報(bào)錯(cuò)。編譯器同樣會(huì)檢測 override 標(biāo)記的方法是否確實(shí)在父類中。
處理變量的可選值時(shí),可以在操作(比如方法、屬性和子腳本)之前加 ? 。如果 ? 之前的值是 nil , ? 后面 的東西都會(huì)被忽略,并且整個(gè)表達(dá)式返回 nil 。否則, ? 之后的東西都會(huì)被運(yùn)行。在這兩種情況下,整個(gè)表達(dá)式 的值也是一個(gè)可選值。
(2)枚舉和結(jié)構(gòu)體
- 使用 enum 來創(chuàng)建一個(gè)枚舉。和其他所有命名類型一樣,枚舉可以包含方法。
- 一個(gè)枚舉成員的實(shí)例可以有實(shí)例值。相同枚舉成員的實(shí)例可以有不同的值。創(chuàng)建實(shí)例的時(shí)候傳入值即可。實(shí)例值和原始值是不同的:枚舉成員的原始值對(duì)于所有實(shí)例都是相同的,而且在定義枚舉的時(shí)候設(shè)置原始值。
enum ServerResponse {
case Result(String, String)
case Failure(String)
}
let success = ServerResponse.Result("6:00 am", "8:09 pm")
let failure = ServerResponse.Failure("Out of cheese.")
switch success {
case let .Result(sunrise, sunset):
let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
case let .Failure(message):
print("Failure... \(message)")
}
- 使用 struct 來創(chuàng)建一個(gè)結(jié)構(gòu)體。結(jié)構(gòu)體和類有很多相同的地方,比如方法和構(gòu)造器。它們之間最大的一個(gè)區(qū)別就 是結(jié)構(gòu)體是傳值,類是傳引用。
struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
} }
let threeOfSpades = Card(rank: .Three, suit: .Spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()
(3)協(xié)議和擴(kuò)展
- 使用 protocol 來聲明一個(gè)協(xié)議。
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}
- 類、枚舉和結(jié)構(gòu)體都可以實(shí)現(xiàn)協(xié)議。
class SimpleClass: ExampleProtocol {
var simpleDescription: String = "A very simple class."
var anotherProperty: Int = 69105
func adjust() {
simpleDescription += " Now 100% adjusted."
}
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription
struct SimpleStructure: ExampleProtocol {
var simpleDescription: String = "A simple structure"
mutating func adjust() {
simpleDescription += " (adjusted)"
}
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription
注意: 聲明 SimpleStructure 時(shí)候 mutating 關(guān)鍵字用來標(biāo)記一個(gè)會(huì)修改結(jié)構(gòu)體的方法。 SimpleClass 的聲明不需要 標(biāo)記任何方法,因?yàn)轭愔械姆椒ㄍǔ?梢孕薷念悓傩?類的性質(zhì))。
- 使用 extension 來為現(xiàn)有的類型添加功能,比如新的方法和計(jì)算屬性。你可以使用擴(kuò)展在別處修改定義,甚至是 從外部庫或者框架引入的一個(gè)類型,使得這個(gè)類型遵循某個(gè)協(xié)議。
extension Int: ExampleProtocol {
var simpleDescription: String {
return "The number \(self)"
}
mutating func adjust() {
self += 42 }
}
print(7.simpleDescription)
可以像使用其他命名類型一樣使用協(xié)議名——例如,創(chuàng)建一個(gè)有不同類型但是都實(shí)現(xiàn)一個(gè)協(xié)議的對(duì)象 合。當(dāng)處理類型是協(xié)議的值時(shí),協(xié)議外定義的方法不可用。
let protocolValue: ExampleProtocol = a print(protocolValue.simpleDescription)
// print(protocolValue.anotherProperty) // 去掉注釋可以看到錯(cuò)誤
即使 protocolValue 變量運(yùn)行時(shí)的類型是 simpleClass ,編譯器會(huì)把它的類型當(dāng)做 ExampleProtocol 。這表示你不能調(diào)用類在它實(shí)現(xiàn)的協(xié)議之外實(shí)現(xiàn)的方法或者屬性。
(4)泛型
- 在尖括號(hào)里寫一個(gè)名字來創(chuàng)建一個(gè)泛型函數(shù)或者類型。
func repeatItem<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {
var result = [Item]()
for _ in 0..<numberOfTimes {
result.append(item)
}
return result
}
repeatItem(repeating: "knock", numberOfTimes:4)
- 我們也可以創(chuàng)建泛型函數(shù)、方法、類、枚舉和結(jié)構(gòu)體。
// 重新實(shí)現(xiàn) Swift 標(biāo)準(zhǔn)庫中的可選類型 enum OptionalValue<Wrapped> {
case None
case Some(Wrapped)
}
var possibleInteger: OptionalValue<Int> = .None
possibleInteger = .Some(100)
- 在類型名后面使用 where 來指定對(duì)類型的需求,比如,限定類型實(shí)現(xiàn)某一個(gè)協(xié)議,限定兩個(gè)類型是相同的,或者 限定某個(gè)類必須有一個(gè)特定的父類。
func anyCommonElements<T: Sequence, U: Sequence>(_ lhs: T, _ rhs: U) -> Bool
where T.Iterator.Element: Equatable, T.Iterator.Element == U.Iterator.Element {
for lhsItem in lhs {
for rhsItem in rhs {
if lhsItem == rhsItem {
return true
} }
}
return false
}
anyCommonElements([1, 2, 3], [3])
<T: Equatable> 和 <T> ... where T: Equatable> 是等價(jià)的。