swift基礎(chǔ)03

1.前言:

Swift包含了 CObjective-C上所有基礎(chǔ)數(shù)據(jù)類型状植,Int表示整型值优炬; DoubleFloat表示浮點(diǎn)型值; Bool是布爾型值境蔼;String是文本型數(shù)據(jù)。 Swift 還提供了三個(gè)基本的集合類型伺通,Array 箍土,SetDictionary

Swift 中罐监,廣泛的使用著值不可變的變量吴藻,它們就是常量。而且比 C 語言的常量更強(qiáng)大弓柱。在 Swift 中沟堡,如果你要處理的值不需要改變侧但,那使用常量可以讓你的代碼更加安全并且更清晰地表達(dá)你的意圖。

Swift 是一門類型安全的語言航罗,可選類型就是一個(gè)很好的例子禀横。

2.字符串插值

Swift用字符串插值(string interpolation)的方式把常量名或者變量名當(dāng)做占位符加入到長字符串中,Swift 會用當(dāng)前常量或變量的值替換這些占位符粥血。

var friendlyWelcome = "朋友你好柏锄!"
print("The current value of friendlyWelcome is \(friendlyWelcome)")
// 輸出 "The current value of friendlyWelcome is Bonjour!
  1. 類型推斷

    let possibleNumber = "123"
    let convertedNumber = Int(possibleNumber)
    // convertedNumber 被推測為類型 "Int?", 或者類型 "optional Int"
    如果possibleNumber 是"asdas复亏,那么convertedNumber就是nil

4.nil

你可以給可選變量賦值為nil來表示它沒有值:

var surveyAnswer: String?
// surveyAnswer 被自動設(shè)置為 nil

SwiftnilObjective-C 中的 nil 并不一樣趾娃。在 Objective-C 中,nil 是一個(gè)指向不存在對象的指針缔御。在 Swift 中抬闷,nil不是指針——它是一個(gè)確定的值,用來表示值缺失耕突。任何類型的可選狀態(tài)都可以被設(shè)置為 nil笤成,不只是對象類型。

5.隱式解析可選類型

把想要用作可選的類型的后面的問號(String?)改成感嘆號(String!)來聲明一個(gè)隱式解析可選類型有勾。

可以把隱式解析可選類型當(dāng)做一個(gè)可以自動解析的可選類型疹启。你要做的只是聲明的時(shí)候把感嘆號放到類型的結(jié)尾,而不是每次取值的可選名字的結(jié)尾蔼卡。

6.錯(cuò)誤處理

你可以使用 錯(cuò)誤處理(error handling) 來應(yīng)對程序執(zhí)行中可能會遇到的錯(cuò)誤條件喊崖。

1)函數(shù)throws

7.集合類型

Swift 語言提供ArraysSetsDictionaries三種基本的集合類型用來存儲集合數(shù)據(jù)雇逞。數(shù)組(Arrays)是有序數(shù)據(jù)的集荤懂。集合(Sets)是無序無重復(fù)數(shù)據(jù)的集。字典(Dictionaries)是無序的鍵值對的集塘砸。

SwiftArrays节仿、SetsDictionaries類型被實(shí)現(xiàn)為泛型集合。

在我們不需要改變集合的時(shí)候創(chuàng)建不可變集合是很好的實(shí)踐掉蔬。如此 Swift 編譯器可以優(yōu)化我們創(chuàng)建的集合廊宪。 SwiftArray類型被橋接到Foundation中的NSArray
1)數(shù)組
通過兩個(gè)數(shù)組相加創(chuàng)建一個(gè)數(shù)組

var threeDoubles = [Double](repeating: 0.0, count: 3)
var anotherThreeDoubles = [Double](repeatElement(0.125, count: 3))
var sixDoubles = threeDoubles + anotherThreeDoubles

可以使用數(shù)組的只讀屬性count來獲取數(shù)組中的數(shù)據(jù)項(xiàng)數(shù)量:

2)集合(Sets)

集合(Set)用來存儲相同類型并且沒有確定順序的值。當(dāng)集合元素順序不重要時(shí)或者希望確保每個(gè)元素只出現(xiàn)一次時(shí)可以使用集合而不是數(shù)組女轿。

SwiftSet類型被橋接到Foundation中的NSSet類箭启。

集合類型的哈希值
一個(gè)類型為了存儲在集合中,該類型必須是可哈向燃#化

一個(gè)類型為了存儲在集合中傅寡,該類型必須是可哈希化的--也就是說,該類型必須提供一個(gè)方法來計(jì)算它的哈希值荐操。一個(gè)哈希值是Int類型的芜抒,相等的對象哈希值必須相同,比如a==b,因此必須a.hashValue == b.hashValue托启。

Swift 的所有基本類型(比如String,Int,Double和Bool)默認(rèn)都是可哈险梗化的,可以作為集合的值的類型或者字典的鍵的類型驾中。沒有關(guān)聯(lián)值的枚舉成員值(在枚舉有講述)默認(rèn)也是可哈习埃化的。

Swift 中的Set類型被寫為Set<Element>肩民,這里的Element表示Set中允許存儲的類型唠亚,和數(shù)組不同的是,集合沒有等價(jià)的簡化形式持痰。

*注意:集合要聯(lián)想起我們高中數(shù)學(xué)的集合灶搜。

使用intersect(_:)方法根據(jù)兩個(gè)集合中都包含的值創(chuàng)建的一個(gè)新的集合。
使用exclusiveOr(_:)方法根據(jù)在一個(gè)集合中但不在兩個(gè)集合中的值創(chuàng)建一個(gè)新的集合工窍。
使用union(_:)方法根據(jù)兩個(gè)集合的值創(chuàng)建一個(gè)新的集合割卖。
使用subtract(_:)方法根據(jù)不在該集合中的值創(chuàng)建一個(gè)新的集合。

3)字典

SwiftDictionary類型被橋接到FoundationNSDictionary類患雏。

字典是一種存儲多個(gè)相同類型的值的容器鹏溯。每個(gè)值(value)都關(guān)聯(lián)唯一的鍵(key),鍵作為字典中的這個(gè)值數(shù)據(jù)的標(biāo)識符淹仑。和數(shù)組中的數(shù)據(jù)項(xiàng)不同丙挽,字典中的數(shù)據(jù)項(xiàng)并沒有具體順序。我們在需要通過標(biāo)識符(鍵)訪問數(shù)據(jù)的時(shí)候使用字典匀借,這種方法很大程度上和我們在現(xiàn)實(shí)世界中使用字典查字義的方法一樣颜阐。

Swift的字典使用Dictionary<Key, Value>定義,其中Key是字典中鍵的數(shù)據(jù)類型吓肋,Value是字典中對應(yīng)于這些鍵所存儲值的數(shù)據(jù)類型凳怨。

創(chuàng)建一個(gè)空字典

var namesOfIntegers = [Int: String]()
// namesOfIntegers 是一個(gè)空的 [Int: String] 字典

8.控制流

提前退出

if語句一樣,guard的執(zhí)行取決于一個(gè)表達(dá)式的布爾值是鬼。我們可以使用guard語句來要求條件必須為真時(shí)肤舞,以執(zhí)行guard語句后的代碼。不同于if語句均蜜,一個(gè)guard語句總是有一個(gè)else從句萨赁,如果條件不為真則執(zhí)行else從句中的代碼。

9.檢測 API 可用性

if #available(iOS 10, macOS 10.12, *) {
    // 在 iOS 使用 iOS 10 的 API, 在 macOS 使用 macOS 10.12 的 API
} else {
    // 使用先前版本的 iOS 和 macOS 的 API
}

10.函數(shù)

參數(shù)標(biāo)簽 (Specifying Argument Labels)
可以在函數(shù)名稱前指定它的參數(shù)標(biāo)簽兆龙,中間以空格分隔:

func someFunction(argumentLabel parameterName: Int) {
    // In the function body, parameterName refers to the argument value
    // for that parameter.
}

func greet(person: String, from hometown: String) -> String {
    return "Hello \(person)!  Glad you could visit from \(hometown)."
}
print(greet(person: "Bill", from: "Cupertino"))
// Prints "Hello Bill!  Glad you could visit from Cupertino."

*注意:這里的from 就是參數(shù)hometown的標(biāo)簽

參數(shù)標(biāo)簽的使用能夠讓一個(gè)函數(shù)在調(diào)用時(shí)更有表達(dá)力,更類似自然語言,并且仍保持了函數(shù)內(nèi)部的可讀性以及清晰的意圖紫皇。

忽略參數(shù)標(biāo)簽(Omitting Argument Labels)
如果不希望為某個(gè)參數(shù)添加一個(gè)標(biāo)簽慰安,可以使用一個(gè)下劃線(_)來代替一個(gè)明確的參數(shù)標(biāo)簽。

func someFunction(_ firstParameterName: Int, secondParameterName: Int) {
    // In the function body, firstParameterName and secondParameterName
    // refer to the argument values for the first and second parameters.
}
someFunction(1, secondParameterName: 2)

可變參數(shù) (Variadic Parameters)
一個(gè)可變參數(shù)(variadic parameter)可以接受零個(gè)或多個(gè)值聪铺。通過在變量類型名后面加入(...)的方式來定義可變參數(shù)

一個(gè)函數(shù)最多只能擁有一個(gè)可變參數(shù)化焕。

輸入輸出參數(shù)(In-Out Parameters
函數(shù)參數(shù)默認(rèn)是常量。

只能傳遞變量給輸入輸出參數(shù)铃剔。你不能傳入常量或者字面量literal value)撒桨,因?yàn)檫@些量是不能被修改的。當(dāng)傳入的參數(shù)作為輸入輸出參數(shù)時(shí)键兜,需要在參數(shù)名前加 &符凤类,表示這個(gè)值可以被函數(shù)修改。

eg: 

函數(shù)類型 (Function Types)
每個(gè)函數(shù)都有種特定的函數(shù)類型普气,函數(shù)的類型由函數(shù)的參數(shù)類型返回類型組成谜疤。

func eschop(_ a: Strinfg, _b: Int) -> String {
    // func body
} 
函數(shù)類型為:(String, Int) -> String

嵌套函數(shù)
可以把函數(shù)定義在別的函數(shù)體中,稱作 嵌套函數(shù)(nested functions
默認(rèn)情況下现诀,嵌套函數(shù)是對外界不可見的夷磕,但是可以被它們的外圍函數(shù)enclosing function)調(diào)用。

func chooseStepFunction(backward: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backward ? stepBackward : stepForward
}
var currentValue = -4
let moveNearerToZero = chooseStepFunction(backward: currentValue > 0)
// moveNearerToZero now refers to the nested stepForward() function
while currentValue != 0 {
    print("\(currentValue)... ")
    currentValue = moveNearerToZero(currentValue)
}
print("zero!")
// -4...
// -3...
// -2...
// -1...
// zero!

11.閉包(Closures

閉包自包含函數(shù)代碼塊仔沿,可以在代碼中被傳遞使用坐桩。Swift中的閉包CObjective-C 中的代碼塊(blocks)以及其他一些編程語言中的匿名函數(shù)比較相似。

閉包可以捕獲和存儲其所在上下文中任意常量變量的引用封锉。閉合绵跷、包裹常量和變量,所謂閉包也烘浦。Swift會為你管理在捕獲過程中涉及到的所有內(nèi)存操作抖坪。

捕獲(capturing):閉包可以在其被定義的上下文中捕獲常量或變量。即使定義這些常量和變量的原作用域已經(jīng)不存在闷叉,閉包仍然可以在閉包函數(shù)體內(nèi)引用和修改這些值擦俐。
Swift 中,可以捕獲值的閉包的最簡單形式是嵌套函數(shù)握侧,也就是定義在其他函數(shù)的函數(shù)體內(nèi)的函數(shù)蚯瞧。嵌套函數(shù)可以捕獲其外部函數(shù)所有的參數(shù)以及定義的常量和變量。

全局和嵌套函數(shù)實(shí)際上也是特殊的閉包:
閉包采取如下三種形式之一:
·全局函數(shù)是一個(gè)有名字但不會捕獲任何值的閉包
·嵌套函數(shù)是一個(gè)有名字并可以捕獲其封閉函數(shù)域內(nèi)值的閉包
·閉包表達(dá)式是一個(gè)利用輕量級語法所寫的可以捕獲其上下文中變量或常量值的匿名閉包

如果你將閉包賦值給一個(gè)類實(shí)例的屬性品擎,并且該閉包通過訪問該實(shí)例或其成員而捕獲了該實(shí)例埋合,你將在閉包和該實(shí)例間創(chuàng)建一個(gè)循環(huán)強(qiáng)引用。Swift 使用捕獲列表來打破這種循環(huán)強(qiáng)引用萄传。

Swift 的閉包表達(dá)式擁有簡潔的風(fēng)格甚颂,并鼓勵在常見場景中進(jìn)行語法優(yōu)化,主要優(yōu)化如下:
1)利用上下文推斷參數(shù)和返回值類型
2)隱式返回單表達(dá)式閉包,即單表達(dá)式閉包可以省略 return 關(guān)鍵字
3)參數(shù)名稱縮寫
4)尾隨(Trailing)閉包語法

閉包表達(dá)式(Closure Expressions

嵌套函數(shù)是一個(gè)在較復(fù)雜函數(shù)中方便進(jìn)行命名和定義自包含代碼模塊的方式振诬。
當(dāng)然蹭睡,有時(shí)候編寫小巧的沒有完整定義和命名的類函數(shù)結(jié)構(gòu)也是很有用處的,尤其是在你處理一些函數(shù)并需要將另外一些函數(shù)作為該函數(shù)的參數(shù)時(shí)赶么。

閉包表達(dá)式是一種利用簡潔語法構(gòu)建內(nèi)聯(lián)閉包的方式肩豁。
閉包表達(dá)式提供了一些語法優(yōu)化,使得撰寫閉包變得簡單明了辫呻。

sorted(by:) 方法接受一個(gè)閉包清钥,該閉包函數(shù)需要傳入與數(shù)組元素類型相同的兩個(gè)值,并返回一個(gè)布爾類型值來表明當(dāng)排序結(jié)束后傳入的第一個(gè)參數(shù)排在第二個(gè)參數(shù)前面還是后面放闺。如果第一個(gè)參數(shù)值出現(xiàn)在第二個(gè)參數(shù)值前面祟昭,排序閉包函數(shù)需要返回true,反之返回false雄人。

利用閉包表達(dá)式語法可以更好地構(gòu)造一個(gè)內(nèi)聯(lián)排序閉包从橘。

閉包表達(dá)式語法(Closure Expression Syntax

閉包表達(dá)式語法有如下的一般形式:
閉包表達(dá)式的參數(shù)可以是inout參數(shù),但不能設(shè)定默認(rèn)值础钠。
也可以使用具名的可變參數(shù).元組也可以作為參數(shù)和返回值恰力。
內(nèi)聯(lián)閉包參數(shù)和返回值類型聲明與 backward(::) 函數(shù)類型聲明相同。在內(nèi)聯(lián)閉包表達(dá)式中旗吁,函數(shù)和返回值類型都寫在大括號內(nèi)踩萎,而不是大括號外。

reversedNames = names.sorted(by: { s1, s2 in return s1 > s2 } )

根據(jù)上下文推斷類型(Inferring Type From Context

通過內(nèi)聯(lián)閉包表達(dá)式構(gòu)造的閉包作為參數(shù)傳遞給函數(shù)或方法時(shí)很钓,總是能夠推斷出閉包的參數(shù)和返回值類型香府。

單表達(dá)式閉包隱式返回(Implicit Returns From Single-Expression Closures

單行表達(dá)式閉包可以通過省略 return 關(guān)鍵字來隱式返回單行表達(dá)式的結(jié)果,如上版本的例子可以改寫為:

reversedNames = names.sorted(by: { s1, s2 in s1 > s2 } )

參數(shù)名稱縮寫(Shorthand Argument Names

reversedNames = names.sorted(by: { $0 > $1 } )

在這個(gè)例子中码倦,$0和$1表示閉包中第一個(gè)和第二個(gè) String 類型的參數(shù)企孩。

運(yùn)算符方法(Operator Methods
SwiftString類型定義了關(guān)于大于號(>)的字符串實(shí)現(xiàn),其作為一個(gè)函數(shù)接受兩個(gè) String 類型的參數(shù)并返回 Bool類型的值袁稽。而這正好與 sorted(by:) 方法的參數(shù)需要的函數(shù)類型相符合勿璃。因此,你可以簡單地傳遞一個(gè)大于號推汽,Swift 可以自動推斷出你想使用大于號的字符串函數(shù)實(shí)現(xiàn):

reversedNames = names.sorted(by: >)

尾隨閉包(Trailing Closures

如果你需要將一個(gè)很長的閉包表達(dá)式作為最后一個(gè)參數(shù)傳遞給函數(shù)补疑,可以使用尾隨閉包來增強(qiáng)函數(shù)的可讀性。

尾隨閉包是一個(gè)書寫在函數(shù)括號之后的閉包表達(dá)式歹撒,函數(shù)支持將其作為最后一個(gè)參數(shù)調(diào)用莲组。在使用尾隨閉包時(shí),你不用寫出它的參數(shù)標(biāo)簽:

func someFunctionThatTakesAClosure(closure: () -> Void) {
    // 函數(shù)體部分
}

// 以下是不使用尾隨閉包進(jìn)行函數(shù)調(diào)用
someFunctionThatTakesAClosure(closure: {
    // 閉包主體部分
})

// 以下是使用尾隨閉包進(jìn)行函數(shù)調(diào)用
someFunctionThatTakesAClosure() {
    // 閉包主體部分
}

reversedNames = names.sorted() { $0 > $1 }  // 方法參數(shù)的字符串排序閉包可以改寫為:
reversedNames = names.sorted { $0 > $1 }  // 如果閉包表達(dá)式是函數(shù)或方法的唯一參數(shù)暖夭,則當(dāng)你使用尾隨閉包時(shí)锹杈,你甚至可以把 () 省略掉

當(dāng)閉包非常長以至于不能在一行中進(jìn)行書寫時(shí)撵孤,尾隨閉包變得非常有用。
舉例來說嬉橙,SwiftArray 類型有一個(gè) map(_:) 方法早直,這個(gè)方法獲取一個(gè)閉包表達(dá)式作為其唯一參數(shù)。該閉包函數(shù)會為數(shù)組中的每一個(gè)元素調(diào)用一次市框,并返回該元素所映射的值。具體的映射方式和返回值類型由閉包來指定糕韧。

閉包是引用類型(Closures Are Reference Types)

無論你將函數(shù)或閉包賦值給一個(gè)常量還是變量枫振,你實(shí)際上都是將常量或變量的值設(shè)置為對應(yīng)函數(shù)或閉包的引用。

逃逸閉包(Escaping Closures)

當(dāng)一個(gè)閉包作為參數(shù)傳到一個(gè)函數(shù)中萤彩,但是這個(gè)閉包在函數(shù)返回之后才被執(zhí)行粪滤,我們稱該閉包從函數(shù)中逃逸
當(dāng)你定義接受閉包作為參數(shù)的函數(shù)時(shí)雀扶,你可以在參數(shù)名之前標(biāo)注 @escaping杖小,用來指明這個(gè)閉包是允許“逃逸”出這個(gè)函數(shù)的。

一種能使閉包“逃逸”出函數(shù)的方法是愚墓,將這個(gè)閉包保存在一個(gè)函數(shù)外部定義的變量中予权。舉個(gè)例子,很多啟動異步操作的函數(shù)接受一個(gè)閉包參數(shù)作為completion handler浪册。這類函數(shù)會在異步操作開始之后立刻返回扫腺,但是閉包直到異步操作結(jié)束后才會被調(diào)用。在這種情況下村象,閉包需要“逃逸”出函數(shù)笆环,因?yàn)殚]包需要在函數(shù)返回之后被調(diào)用。例如:

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

someFunctionWithEscapingClosure(_:)函數(shù)接受一個(gè)閉包作為參數(shù)厚者,該閉包被添加到一個(gè)函數(shù)外定義的數(shù)組中躁劣。如果你不將這個(gè)參數(shù)標(biāo)記為 @escaping,就會得到一個(gè)編譯錯(cuò)誤库菲。

自動閉包(Autoclosures)

自動閉包是一種自動創(chuàng)建的閉包账忘,用于包裝傳遞給函數(shù)作為參數(shù)的表達(dá)式。這種閉包不接受任何參數(shù)蝙昙,當(dāng)它被調(diào)用的時(shí)候闪萄,會返回被包裝在其中的表達(dá)式的值。這種便利語法讓你能夠省略閉包的花括號奇颠,用一個(gè)普通的表達(dá)式來代替顯式的閉包败去。

12.枚舉

可以定義 Swift 枚舉來存儲任意類型的關(guān)聯(lián)值,如果需要的話烈拒,每個(gè)枚舉成員的關(guān)聯(lián)值類型可以各不相同圆裕。枚舉的這種特性跟其他語言中的可識別聯(lián)合(discriminated unions)广鳍,標(biāo)簽聯(lián)合(tagged unions),或者變體(variants)相似吓妆。

原始值(Raw Values)
在關(guān)聯(lián)值小節(jié)的條形碼例子中赊时,演示了如何聲明存儲不同類型關(guān)聯(lián)值的枚舉成員。作為關(guān)聯(lián)值的替代選擇行拢,枚舉成員可以被默認(rèn)值(稱為原始值)預(yù)填充祖秒,這些原始值的類型必須相同。

原始值的隱式賦值(Implicitly Assigned Raw Values)

enum Planet: Int {
    case mercury = 1, venus, earth, mars, jupiter, saturn, uranus, neptune
}

當(dāng)使用字符串作為枚舉類型的原始值時(shí)舟奠,每個(gè)枚舉成員的隱式原始值為該枚舉成員的名稱竭缝。

enum CompassPoint: String {
    case north, south, east, west
}

上面例子中,CompassPoint.south擁有隱式原始值south沼瘫,依次類推抬纸。

使用原始值初始化枚舉實(shí)例(Initializing from a Raw Value)

let possiblePlanet = Planet(rawValue: 7)
// possiblePlanet 類型為 Planet? 值為 Planet.uranus

13.類和結(jié)構(gòu)體

類和結(jié)構(gòu)體是人們構(gòu)建代碼所用的一種通用且靈活的構(gòu)造體。我們可以使用完全相同的語法規(guī)則來為類和結(jié)構(gòu)體定義屬性(常量耿戚、變量)和添加方法湿故,從而擴(kuò)展類和結(jié)構(gòu)體的功能。

Swift 中類和結(jié)構(gòu)體有很多共同點(diǎn)膜蛔。共同處在于:
定義屬性用于存儲值
定義方法用于提供功能
定義下標(biāo)操作使得可以通過下標(biāo)語法來訪問實(shí)例所包含的值
定義構(gòu)造器用于生成初始化值
通過擴(kuò)展以增加默認(rèn)實(shí)現(xiàn)的功能
實(shí)現(xiàn)協(xié)議以提供某種標(biāo)準(zhǔn)功能

每次定義一個(gè)新類或者結(jié)構(gòu)體的時(shí)候坛猪,實(shí)際上你是定義了一個(gè)新的Swift 類型。

struct Resolution {
    var width = 0
    var height = 0
}
class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
}

let hd = Resolution(width: 1920, height: 1080)
var cinema = hd

在以上示例中飞几,聲明了一個(gè)名為hd的常量砚哆,其值為一個(gè)初始化為全高清視頻分辨率(1920 像素寬,1080 像素高)的Resolution實(shí)例屑墨。

然后示例中又聲明了一個(gè)名為cinema的變量躁锁,并將hd賦值給它。因?yàn)?code>Resolution是一個(gè)結(jié)構(gòu)體,所以cinema的值其實(shí)是hd的一個(gè)拷貝副本,而不是hd本身薇组。盡管hdcinema有著相同的寬(width)和高(height)型型,但是在幕后它們是兩個(gè)完全不同的實(shí)例正什。

類是引用類型

let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0

let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0

因?yàn)轭愂且妙愋停?code>tenEight和alsoTenEight實(shí)際上引用的是相同的VideoMode實(shí)例。換句話說,它們是同一個(gè)實(shí)例的兩種叫法刁标。

恒等運(yùn)算符

因?yàn)轭愂且妙愋停锌赡苡卸鄠€(gè)常量和變量在幕后同時(shí)引用同一個(gè)類實(shí)例址晕。

如果能夠判定兩個(gè)常量或者變量是否引用同一個(gè)類實(shí)例將會很有幫助膀懈。為了達(dá)到這個(gè)目的,Swift 內(nèi)建了兩個(gè)恒等運(yùn)算符:

等價(jià)于(===
不等價(jià)于(!==

指針,使用指針來引用內(nèi)存中的地址

一個(gè)引用某個(gè)引用類型實(shí)例的 Swift 常量或者變量谨垃,與 C 語言中的指針類似启搂,但是并不直接指向某個(gè)內(nèi)存地址硼控,也不要求你使用星號(*)來表明你在創(chuàng)建一個(gè)引用。Swift 中的這些引用與其它的常量或變量的定義方式相同胳赌。

在所有其它案例中牢撼,定義一個(gè)類,生成一個(gè)它的實(shí)例疑苫,并通過引用來管理和傳遞熏版。實(shí)際中,這意味著絕大部分的自定義數(shù)據(jù)構(gòu)造都應(yīng)該是類缀匕,而非結(jié)構(gòu)體纳决。

字符串(String)、數(shù)組(Array)乡小、和字典(Dictionary)類型的賦值與復(fù)制行為

Swift 中,許多基本類型饵史,諸如String满钟,ArrayDictionary類型均以結(jié)構(gòu)體的形式實(shí)現(xiàn)。這意味著被賦值給新的常量變量胳喷,或者被傳入函數(shù)或方法中時(shí)湃番,它們的值會被拷貝

Objective-CNSString吭露,NSArrayNSDictionary類型均以類的形式實(shí)現(xiàn)吠撮,而并非結(jié)構(gòu)體。它們在被賦值或者被傳入函數(shù)或方法時(shí)讲竿,不會發(fā)生值拷貝泥兰,而是傳遞現(xiàn)有實(shí)例的引用。

以上是對字符串题禀、數(shù)組鞋诗、字典的“拷貝”行為的描述。在你的代碼中迈嘹,拷貝行為看起來似乎總會發(fā)生削彬。然而,Swift 在幕后只在絕對必要時(shí)才執(zhí)行實(shí)際的拷貝秀仲。Swift 管理所有的值拷貝以確保性能最優(yōu)化融痛,所以你沒必要去回避賦值來保證性能最優(yōu)化。

14.屬性

屬性將值跟特定的神僵、結(jié)構(gòu)枚舉關(guān)聯(lián)雁刷。存儲屬性存儲常量或變量作為實(shí)例的一部分,而計(jì)算屬性計(jì)算(不是存儲)一個(gè)值挑豌。計(jì)算屬性可以用于類安券、結(jié)構(gòu)體和枚舉墩崩,存儲屬性只能用于結(jié)構(gòu)體

存儲屬性和計(jì)算屬性通常與特定類型的實(shí)例關(guān)聯(lián)侯勉。但是鹦筹,屬性也可以直接作用于類型本身,這種屬性稱為類型屬性址貌。

存儲屬性

常量結(jié)構(gòu)體的存儲屬性

延遲存儲屬性
延遲存儲屬性是指當(dāng)?shù)谝淮伪徽{(diào)用的時(shí)候才會計(jì)算其初始值的屬性铐拐。在屬性聲明前使用 lazy 來標(biāo)示一個(gè)延遲存儲屬性。

存儲屬性和實(shí)例變量

如果您有過 Objective-C 經(jīng)驗(yàn)练对,應(yīng)該知道 Objective-C 為類實(shí)例存儲值和引用提供兩種方法遍蟋。除了屬性之外,還可以使用實(shí)例變量作為屬性值的后端存儲螟凭。

便捷 setter 聲明

全局變量和局部變量

計(jì)算屬性和屬性觀察器所描述的功能也可以用于全局變量和局部變量虚青。全局變量是在函數(shù)、方法螺男、閉包或任何類型之外定義的變量棒厘。局部變量是在函數(shù)、方法或閉包內(nèi)部定義的變量下隧。

全局的常量或變量都是延遲計(jì)算的奢人,跟延遲存儲屬性相似,不同的地方在于淆院,全局的常量或變量不需要標(biāo)記lazy修飾符何乎。
局部范圍的常量或變量從不延遲計(jì)算。

類型屬性

類型屬性語法

15.方法(Methods)

方法是與某些特定類型相關(guān)聯(lián)的函數(shù)土辩。
類支救、結(jié)構(gòu)體、枚舉都可以定義實(shí)例方法脯燃。
實(shí)例方法為給定類型的實(shí)例封裝了具體的任務(wù)與功能搂妻。
類、結(jié)構(gòu)體辕棚、枚舉也可以定義類型方法欲主;類型方法與類型本身相關(guān)聯(lián)。類型方法與 Objective-C 中的類方法(class methods)相似逝嚎。

修改方法的外部參數(shù)名稱(Modifying External Parameter Name Behavior for Methods)

有時(shí)為方法的第一個(gè)參數(shù)提供一個(gè)外部參數(shù)名稱是非常有用的扁瓢,盡管這不是默認(rèn)的行為。你自己可以為第一個(gè)參數(shù)添加一個(gè)顯式的外部名稱补君。
相反引几,如果你不想為方法的第二個(gè)及后續(xù)的參數(shù)提供一個(gè)外部名稱,可以通過使用下劃線(_)作為該參數(shù)的顯式外部名稱,這樣做將覆蓋默認(rèn)行為伟桅。

self 屬性

類型的每一個(gè)實(shí)例都有一個(gè)隱含屬性叫做self敞掘,self完全等同于該實(shí)例本身。你可以在一個(gè)實(shí)例的實(shí)例方法中使用這個(gè)隱含的self屬性來引用當(dāng)前實(shí)例楣铁。

在實(shí)例方法中修改值類型

結(jié)構(gòu)體和枚舉是值類型玖雁。默認(rèn)情況下,值類型的屬性不能在它的實(shí)例方法中被修改盖腕。

類型方法 (Type Methods)

實(shí)例方法是被某個(gè)類型的實(shí)例調(diào)用的方法赫冬。你也可以定義在類型本身上調(diào)用的方法,這種方法就叫做類型方法(Type Methods)溃列。在方法的func關(guān)鍵字之前加上關(guān)鍵字static劲厌,來指定類型方法。類還可以用關(guān)鍵字class來允許子類重寫父類的方法實(shí)現(xiàn)听隐。

Objective-C中补鼻,你只能為 Objective-C 的類類型(classes)定義類型方法(type-level methods)。在 Swift 中雅任,你可以為所有的類辽幌、結(jié)構(gòu)體和枚舉定義類型方法。每一個(gè)類型方法都被它所支持的類型顯式包含椿访。

class SomeClass {
    class func someTypeMethod() {
        // type method implementation goes here
    }
}
SomeClass.someTypeMethod()

在類型方法的方法體(body)中,self指向這個(gè)類型本身虑润,而不是類型的某個(gè)實(shí)例成玫。這意味著你可以用self來消除類型屬性和類型方法參數(shù)之間的歧義(類似于我們在前面處理實(shí)例屬性和實(shí)例方法參數(shù)時(shí)做的那樣)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拳喻,一起剝皮案震驚了整個(gè)濱河市哭当,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冗澈,老刑警劉巖钦勘,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異亚亲,居然都是意外死亡彻采,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門捌归,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肛响,“玉大人,你說我怎么就攤上這事惜索√厮瘢” “怎么了?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵巾兆,是天一觀的道長猎物。 經(jīng)常有香客問我虎囚,道長,這世上最難降的妖魔是什么蔫磨? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任淘讥,我火速辦了婚禮,結(jié)果婚禮上质帅,老公的妹妹穿的比我還像新娘适揉。我一直安慰自己,他們只是感情好煤惩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布嫉嘀。 她就那樣靜靜地躺著,像睡著了一般魄揉。 火紅的嫁衣襯著肌膚如雪剪侮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天洛退,我揣著相機(jī)與錄音瓣俯,去河邊找鬼。 笑死兵怯,一個(gè)胖子當(dāng)著我的面吹牛彩匕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播媒区,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼驼仪,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了袜漩?” 一聲冷哼從身側(cè)響起绪爸,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宙攻,沒想到半個(gè)月后奠货,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡座掘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年递惋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雹顺。...
    茶點(diǎn)故事閱讀 39,779評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丹墨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嬉愧,到底是詐尸還是另有隱情贩挣,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站王财,受9級特大地震影響卵迂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜绒净,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一见咒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧挂疆,春花似錦改览、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至胆萧,卻和暖如春庆揩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背跌穗。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工订晌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蚌吸。 一個(gè)月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓锈拨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親羹唠。 傳聞我的和親對象是個(gè)殘疾皇子推励,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容