標籤:
初見:
使用 func 來聲明一個函數,使用名字和參數來調用函數。使用->來指定函數傳回值。
使用一個元組來返回多個值。
函數的參數數量是可變的,用一個數組來擷取它們:func sumOf(numbers: Int...) -> Int
函數可以嵌套。被嵌套的函數可以訪問外側函數的變數,你可以使用嵌套函數來重構一個太 長或者太複雜的函數。
函數是一等公民,這意味著函數可以作為另一個函數的傳回值,函數也可以當做參數傳入另一個函數。
函數實際上是一種特殊的閉包,你可以使用{}來建立一個匿名閉包。使用 in 來分割參數並返 回類型。
有很多種建立閉包的方法。如果一個閉包的類型已知,比如作為一個回呼函數,你可以忽 略參數的類型和傳回值。單個語句閉包會把它語句的值當做結果返回。
你可以通過參數位置而不是參數名字來引用參數——這個方法在非常短的閉包中非常有用。 當一個閉包作為最後一個參數傳給一個函數的時候,它可以直接跟在括弧後面。
如果你不需要計算屬性但是需要在設定一個新值之前或者之後運行一些代碼,使用willSet和didSet。
var variable: Type
{
get{}
set{}willSet{}
didSet{}}
類中的方法和一般的函數有一個重要的區別,函數的參數名只在函數內部使用,但是方法的參數名需要在調用的時候顯式說明(除了第一個參數)。預設情況下,方法的參數名和它在 方法內部的名字一樣,不過你也可以定義第二個名字,這個名字被用在方法內部。
處理變數的可選值時,你可以在操作(比如方法、屬性和子指令碼)之前加?。如果?之前的值是 nil,?後面的東西都會被忽略,並且整個運算式返回 nil。否則,?之後的東西都會被運行。在這兩種情況下,整個運算式的值也是一個可選值。
使用 toRaw 和 fromRaw 函數來在原始值和枚舉值之間進行轉換。
使用 struct 來建立一個結構體。結構體和類有很多相同的地方,比如方法和構造器。它們結 構體之間最大的一個區別就是 結構體是傳值,類是傳引用。
類、枚舉和結構體都可以實現介面。
使用 extension 來為現有的類型添加功能,比如添加一個計算屬性的方法。你可以使用擴充來給任意類型添加協議,甚至是你從外部庫或者架構中匯入的類型。
在角括弧裡寫一個名字來建立一個泛型函數或者類型。
基礎部分:
可選有點像在 Objective-C 中使用 nil,但是它可以用在任何類型上,不僅僅是類。
Swift 是一個型別安全的語言(或者叫做強型別語言)。
有一種情況下必須要用分號,即你打算在同一行內寫多條獨立的語句.
Swift ??提供了 8,16,32 和 64 位元的有符號和不帶正負號的整數類型。
- Double 表示 64 位元浮點數。當你需要儲存很大或者很高精度的浮點數時請使用此類型。- Float 表示 32 位浮點數。精度要求不高的話可以使用此類型。
類型別名(type aliases)就是給現有類型定義另一個名字。你可以使用 typealias 關鍵字來定 義類型別名。
元組(tuples)把多個值組合成一個複合值。元組內的值可以使任意類型,並不要求是相 同類型。
元組在臨時組織值的時候很有用,但是並不適合建立複雜的資料結構。
使用可選綁定(optional binding)來判斷可選是否包含值,如果包含就把值賦給一個臨時常量或者變數。可選綁定可以用在 if 和 while 語句中來對可選的值進行判斷並把值賦給一 個常量或者變數。
nil 不能用於非可選的常量和變數。如果你的代碼中有常量或者變數需要處理值缺失 的情況,請把它們聲明成對應的可選類型。
任何類型的可選都可以被設定為 nil,不只是物件類型。
隱式解析可選(implicitly unwrapped optionals)—當可選被第一次賦值之後就可以確定之後一直有值的時候,隱式解析可選非常有用。隱式 解析可選主要被用在 Swift 中類的構造過程中。
運算子有一目, 雙目和三目運算子.
加法操作 + 也用於字串的拼接:
每個比較運算都返回了一個標識運算式是否成立的布爾值
2.單位元組 Unicode 標量,寫成 \xnn,其中 nn 為兩位十六進位數。3.雙位元組 Unicode 標量,寫成 \unnnn,其中 nnnn 為四位十六進位數。4.四位元組 Unicode 標量,寫成 \Unnnnnnnn,其中 nnnnnnnn 為八位十六進位數。
Swift 的 String 類型是實值型別。
Swift ??供了三種方式來比較字串的值:字串相等,首碼相等和尾碼相等。
Swift 語言??供經典的數組和字典兩種集合類型來儲存集合資料。
寫 Swift 數組應該遵循像 Array<SomeType>這樣的形式,其中 sometype 是這個數組中唯一允許存在的資料類型。 我們也可以使用像 SomeType[]這樣的簡單文法。
Array<sometype> == sometype[]
類型檢查與類型推斷
Swift 的 switch 語句比 C 語言中更加強大。在 C 語言中,如果??個 case 不小心漏寫了 break,這個 case 就會“掉入”下一個 case,Swift 無需寫 break,所以不會發生這種“掉入”的情況。Case 還可以匹配更多的類型模式,包括範圍(range)匹配,元組(tuple)和特定類型的??述。switch case 語句中匹配的值可以是由 case 體內部臨時的常量或者變數決 定,也可以由 where 分句??述更複雜的匹配條件。
case 塊的模式允許將匹配的值綁定到一個臨時的常量或變數,這些常量或變數在該 case 塊 裡就可以被引用了——這種行為被稱為值綁定。
嚴格地說,sayGoodbye 函數確實還返回一個值,即使沒有定義傳回值。沒有 定義傳回型別的函數返回了一個 Void 類型的特殊值。這僅是一個空元組,這裡邊沒有元素,可以被寫成()。
??示:傳回值可以忽略,但一個定義了傳回值的函數則必須有傳回值。對於一個定義了傳回型別的函數來說,如果沒有傳回值,那麼將不允許控制流程離開函數的底部。
這種形參類型名稱被稱之為本地形參名(local parameter name),因為它們只能在函數的主體中使用。
外部形參名:有時當你調用一個函數將每個形參進行命名是非常有用的,以表明你把每個實參傳遞給函數的目的。如果您為形參??供一個外部形參名稱,那麼外部形參名必須在調用時使用。
請在函數形參列表的末尾放置帶預設值的形參。這將確保所有函數調用都使用順序相同的無預設值實參,並讓在每種情況下清晰地調用相同的函數。
函數最多可以有一個可變形參,而且它必須出現在參數列表的最後,以避免使用多個形參調用函數引發歧義。如果你的函數有一個或多個帶有預設值的形參,並且還有可變形參,請將可變形參放在所有預設形參之後,也就是的列表的最末尾。
你對變數形參所做的改變不會比調用函數更持久,並且在函數體外是不可見的。變數形參僅存在於函數調用的聲明周期中。
當你把變數作為實參傳遞給 in out 形參時,需要在直 接在變數前添加 & 符號,以表明它可以被函數修改。in-out 參數不能有預設值,可變參數的參數也不能被標記為 inout。如果您標記 參數為 inout,它不能同時被標記為 var 或 let。
具有相同匹配類型的不同函數可以被賦給同一個變數,和非函數類型一樣.與其他類型一樣,當你給函數賦一個常量或者變數時,你可以讓 Swift 去推斷函數的類型。
在 函數 章節中介紹的全域和嵌套函數實際上也是特殊的閉包,閉包採取如下三種形式之 一:1. 全域函數是一個有名字但不會捕獲任何值的閉包2. 嵌套函數是一個有名字並可以捕獲其封閉函數域內值的閉包3. 閉包運算式是一個利用輕量級文法所寫的可以捕獲其上下文中變數或常量值的沒有名字 的閉包
閉包運算式文法可以使用常量、變數和 inout 類型作為參數,但不??供預設值。 也可以在 參數列表的最後使用可變參數。元組也可以作為參數和傳回值。單行運算式閉包可以省略 return
閉包運算式文法有如下一般形式:{ (parameters) -> returnType in
statements}
如果您需要將一個很長的閉包運算式作為最後一個參數傳遞給函數,可以使用 trailing 閉包來增強函數的可讀性。
Trailing 閉包是一個書寫在函數括弧之外(之後)的閉包運算式,函數支援將其作為最後一個參數調用。如果函數只需要閉包運算式一個參數,當您使用 trailing 閉包時,您甚至可以把() 省略掉。
捕獲 (Caputure)
Swift 最簡單的閉包形式是嵌套函數,也就是定義在其他函數體內的函數。 嵌套函數可以捕 獲其外部函數所有的參數以及定義的常量和變數。
閉包可以在其定義的上下文中捕獲常量或變數。 即使定義這些常量和變數的原範圍已經 不存在,閉包仍然可以在閉包函數體內引用和修改這些值。
無論您將函數/閉包賦值給一個常量還是變數,您實際上都是將常量/變數的值設定為對應函數/閉包的引用。
枚舉
在 Swift 中,枚舉類型是一等(first-class)類型。它們採用了很多傳統上只被類所支援的 特徵,例如計算型屬性(computed properties),用於??供關於枚舉當前值的附加資訊,執行個體方法(instance methods),用於??供和枚舉所代表的值相關聯的功能。枚舉也可以定義 構造器(initializers)來??供一個初始成員值;可以在原始的實現基礎上擴充它們的功能;可以遵守協議(protocols)來??供標準的功能。
注意,原始值和關聯值是不相同的。當你開始在你的代碼中定義枚舉的時候原始值是被預先 填充的值,像上述三個 ASCII 碼。對於一個特定的枚舉成員,它的原始值始終是相同的。 關聯值是當你在建立一個基於枚舉成員的新常量或變數時才會被設定,並且每次當你這麼做 得時候,它的值可以是不同的。
結構體與類
注意:結構體總是通過被複製的方式在代碼中傳遞,因此請不要使用引用計數。
與 Objective-C 語言不同的是,Swift 允許直接設定結構體屬性的子屬性。
所有結構體都有一個自動產生的成員逐一初始化器,用於初始化新結構體執行個體中成員的屬性。新執行個體中各個屬性的初始值可以通過屬性的名稱傳遞到成員逐一初始化器之中:
1. let vga = resolution(width:640, heigth: 480)與結構體不同,類執行個體沒有預設的成員逐一初始化器。
結構體和枚舉是實值型別
實值型別被賦予給一個變數,常數或者本身被傳遞給一個函數的時候,實際上操作的是其的拷貝。實際上,在 Swift 中,所有的基本類型:整數(Integer)、浮點數(floating-point)、布爾值(Booleans)、字串(string)、數組(array)和字典(dictionaries),都是實值型別,並且都是以結構體的形式在後台所實現。
需要注意的是 tenEighty 和 alsoT enEighty 被聲明為常量(constants)而不是變數。然而你依 然可以改變 tenEighty.frameRate 和 alsoTenEighty.frameRate,因為這兩個常量本身不會改 變。它們並不儲存這個 VideoMode 執行個體,在後台僅僅是對 VideoMode 執行個體的引用。所以,改變的是被引用的基礎 VideoMode 的 frameRate 參數,而不改變常量的值。此處常量的值是引用,該引用不可以改變。
Swift 中數組(Array)和字典(Dictionary)類型均以結構體的形式實現。然而當數組被賦予一 個常量或變數,或被傳遞給一個函數或方法時,其拷貝行為與字典和其它結構體有些許不同。
無論何時將一個字典執行個體賦給一個常量或變數,或者傳遞給一個函數或方法,這個字典會即會在賦值或調用發生時被拷貝。
如果字典執行個體中所儲存的鍵(keys)和/或值(values)是實值型別(結構體或枚舉),當賦值或調用 發生時,它們都會被拷貝。相反,如果鍵(keys)和/或值(values)是參考型別,被拷貝的將 會是引用,而不是被它們引用的類執行個體或函數。字典的鍵和值的拷貝行為與結構體所儲存的屬性的拷貝行為相同。
如果你將一個數組(Array)執行個體賦給一個變數或常量,或者將其作為參數傳遞給函數或方法調用,在事件發生時數組的內容不會被拷貝。相反,數組公用相同的元素序列。當你在一個數組內修改??一元素,修改結果也會在另一數組顯示。對數組來說,拷貝行為僅僅當操作有可能修改數組長度時才會發生。這種行為包括了附加(appending),插入(inserting),刪除(removing)或者使用範圍下標(ranged subscript)去替換這 一範圍內的元素。
在操作一個數組,或將其傳遞給函數以及方法調用之前是很有必要先確定這個數組是有一 個唯一拷貝的。通過在陣列變數上調用 unshare 方法來確定數組引用的唯一性。(當數組賦給常量時,不能調用 unshare 方法)如果一個數組被多個變數引用,在其中的一個變數上調用 unshare 方法,則會拷貝此數 組,此時這個變數將會有屬於它自己的獨立數組拷貝。當數組僅被一個變數引用時,則不會有拷貝發生。
儲存屬性、計算屬性、類型屬性、延遲儲存屬性
屬性將值跟特定的類、結構或枚舉關聯。儲存屬性儲存區常量或變數作為執行個體的一部分,計算屬性計算(而不是儲存)一個值。計算屬性可以用於類、結構體和枚舉裡,儲存屬性只能用於類和結構體。
這種行為是由於結構體(struct)屬於實值型別。當實值型別的執行個體被聲明為常量的時候,它的所有屬性也就成了常量。屬於參考型別的類(class)則不一樣,把一個參考型別的執行個體賦給一個常量後,仍然可以修改執行個體的變數屬性。
延遲儲存屬性是指當第一次被調用的時候才會計算其初始值的屬性。在屬性聲明前使用 @lazy 來標示一個延遲儲存屬性。注意:必須將延遲儲存屬性聲明成變數(使用 var 關鍵字),因為屬性的值在執行個體構造完成 之前可能無法得到。而常量屬性在構造過程完成之前必須要有初始值,因此無法聲明成延遲 屬性。
注意:必須使用 var 關鍵字定義計算屬性,包括唯讀計算屬性,因為他們的值不是固定的。let 關鍵字只用來聲明常量屬性,表示初始化後再也無法修改的值。
可以為除了延遲儲存屬性之外的其他儲存屬性添加屬性監視器,也可以通過重載屬性的方式 為繼承的屬性(包括儲存屬性和計算屬性)添加屬性監視器。
注意:willSet 和 didSet 監視器在屬性初始化過程中不會被調用,他們只會當屬性的值在初始化之外的地方被設定時被調用。注意:如果在 didSet 監視器裡為屬性賦值,這個值會替換監視器之前設定的值。
另外,在全域或局部範圍都可以定義計算型變數和為儲存型變數定義監視器,計算型變數跟 計算屬性一樣,返回一個計算的值而不是儲存值,聲明格式也完全一樣。注意:全域的常量或變數都是延遲計算的,跟延遲儲存屬性相似,不同的地方在於,全域的常量或變數不需要標記@lazy 特性;局部範圍的常量或變數不會延遲計算。
對於實值型別(指結構體和枚舉)可以定義儲存型和計算型類型屬性,對於類(class)則只能 定義計算型類型屬性。實值型別的儲存型類型屬性可以是變數或常量,計算型類型屬性跟執行個體的計算屬性一樣定義成變數屬性。
注意:跟執行個體的儲存屬性不同,必須給儲存型類型屬性指定預設值,因為類型本身無法在初始化過程中使用構造器給類型屬性賦值。
使用關鍵字 static 來定義實值型別的類型屬性,關鍵字 class 來為類(class)定義類型屬性。
Swift 預設僅給方法的第一個參數名稱一個局部參數名稱;預設同時給第二個和後 續的參數名稱局部參數名稱和外部參數名稱。
有時為方法的第一個參數??供一個外部參數名稱是非常有用的,儘管這不是預設的行為。你 可以自己添加一個顯式的外部名稱或者用一個井號(#)作為第一個參數的首碼來把這個局 部名稱當作外部名稱使用。相反,如果你不想為方法的第二個及後續的參數??供一個外部名稱,可以通過使用底線(_) 作為該參數的顯式外部名稱,這樣做將覆蓋預設行為。結構體和枚舉是實值型別。一般情況下,實值型別的屬性不能在它的執行個體方法中被修改。
但是,如果你確實需要在??個具體的方法中修改結構體或者枚舉的屬性,你可以選擇變異(mutating)這個方法,然後方法就可以從方法內部改變它的屬性;並且它做的任何改變在方法結束時還會保留在原始結構中。方法還可以給它隱含的 self 屬性賦值一個全新的執行個體,這 個新執行個體在方法結束後將替換原來的執行個體。
聲明類的類型方法,在方法的 func 關鍵字之前加上關鍵字 class;聲明結構 體和枚舉的類型方法,在方法的 func 關鍵字之前加上關鍵字 static。
在類型方法的方法體(body)中,self 指向這個類型本身,而不是類型的??個執行個體。對於結 構體和枚舉來說,這意味著你可以用self來消除靜態屬性和靜態方法參數之間的歧義(類似 於我們在前面處理執行個體屬性和執行個體方法參數時做的那樣)。
一個類型方法可以調用本類中另一個類型方法的名稱,而無需在方法名稱前面加上類型名稱 的首碼。同樣,結構體和枚舉的類型方法也能夠直接通過靜態屬性的名稱訪問靜態屬性,而不需要類型名稱首碼。
根據使用情境不同附屬指令碼也具有不同的含義。通常附屬指令碼是用來訪問集合(collection),例如,Swift 的字典(Dictionary)實現了通過附屬指令碼來對其執行個體中存放的值進行存取操作。 在附屬指令碼中使用和字典索引相同類型的值,並且把一個字典實值型別的值賦值給這個附屬腳 本來為字典設值:列表(list)或序列(sequence)中元素的捷徑。你可以在你自己特定的類或結構體中 自由的實現附屬指令碼來??供合適的功能。
構造器的工作是準備新執行個體以供使用,並確保執行個體中的所有屬性都擁有有效初始化值。
不像 Objective-C,在 Swift 中,初始化器預設是不繼承的,見初始化器的繼承與重 寫
子類可以為繼承來的執行個體方法(instance method),類方法(class method),執行個體屬性(instance property),或附屬指令碼(subscript)??供自己定製的實現(implementation)。 我們把這種行為叫重寫(overriding)。
你可以將一個繼承來的唯讀屬性重寫為一個讀寫屬性,只需要你在重寫版本的屬性裡??供 getter 和 setter 即可。但是,你不可以將一個繼承來的讀寫屬性重寫為一個唯讀屬性。
你不可以同時??供重寫的 setter 和重寫的屬性觀察器。
你可以通過在關鍵字 class 前添加@final 特性(@final class)來將整個類標記為 final 的,這樣的類是不可被繼承的,否則會報編譯錯誤。
構造過程是為了使用??個類、結構體或枚舉類型的執行個體而進行的準備過程。這個過程包含 了為執行個體中的每個屬性設定初始值和為其執行必要的準備和初始化任務。它 們的主要任務是保證新執行個體在第一次使用前完成正確的初始化。類和結構體在執行個體建立時,必須為所有儲存型屬性設定合適的初始值。儲存型屬性的值不能處於一個未知的狀態。
只要在構造過程結束前常量的值能確定,你可以在構造過程中的任意時間點修改常量屬性的值。對??個類執行個體來說,它的常量屬性只能在定義它的類的構造過程中修改;不能在子類中修改。
預設構造器、逐一物件建構器、自己定製構造器
Swift 將為所有屬性已??供預設值的且自身沒有定義任何構造器的結構體或基類,??供一 個預設的構造器。這個預設構造器將簡單的建立一個所有屬性值都設定為預設值的執行個體。
除上面??到的預設構造器,如果“結構體”對所有儲存型屬性??供了預設值且自身沒有??供定製的構造器,它們能自動獲得一個逐一成員構造器。
構造器可以通過調用其它構造器來完成執行個體的部分構造過程。這一過程稱為構造器代理,它能減少多個構造器間的代碼重複。
注意,如果你為??個實值型別定義了一個定製的構造器,你將無法訪問到預設構造器(如果是結構體,則無法訪問逐一物件建構器)。這個限制可以防止你在為實值型別定義了一個更複雜的,完成了重要準備構造器之後,別人還是錯誤的使用了那個自動產生的構造器。
Swift ??供了兩種類型的類構造器來確保所有類執行個體中儲存型屬性都能獲得初始值,它們分別是指定構造器和便利構造器。指定構造器是類中最主要的構造器。一個指定構造器將初始化類中??供的所有屬性,並根據父類鏈往上調用父類的構造器來實現父類的初始化。每一個類都必須擁有至少一個指定構造器。
規則1
指定構造器必須調用其直接父類的的指定構造器。規則 2便利構造器必須調用同一類中定義的其它構造器。規則 3便利構造器必須最終以調用一個指定構造器結束。
一個更方便記憶的方法是:指定構造器必須總是向上代理便利構造器必須總是橫向代理
兩段式構造過程
Swift 中類的構造過程包含兩個階段。第一個階段,每個儲存型屬性通過引入它們的類的 構造器來設定初始值。當每一個儲存型屬性值被確定後,第二階段開始,它給每個類一次機會在新執行個體準備使用之前進一步定製它們的儲存型屬性。
Swift 編譯器將執行 4 種有效安全檢查,以確保兩段式構造過程能順利完成:安全檢查 1 指定構造器必須保證它所在類引入的所有屬性都必須先初始化完成,之後才能將其它構造任務向上代理給父類中的構造器。如上所述,一個對象的記憶體只有在其所有儲存型屬性確定之後才能完全初始化。為了滿足這一規則,指定構造器必須保證它所在類引入的屬性在它往上代理之前先完成初始化。安全檢查 2 指定構造器必須先向上代理調用父類構造器,然後再為繼承的屬性設定新值。如果沒這麼做,指定構造器賦予的新值將被父類中的構造器所覆蓋。安全檢查 3 便利構造器必須先代理調用同一類中的其它構造器,然後再為任意屬性賦新值。如果沒這 麼做,便利構造器賦予的新值將被同一類中其它指定構造器所覆蓋。安全檢查 4 構造器在第一階段構造完成之前,不能調用任何執行個體方法、不能讀取任何執行個體屬性的值, 也不能引用 self 的值。
階段 1??個指定構造器或便利構造器被調用; 完成新執行個體記憶體的分配,但此時記憶體還沒有被初始化;指定構造器確保其所在類引入的所有儲存型屬性都已賦初值。儲存型屬性所屬的記憶體完成初始化;指定構造器將調用父類的構造器,完成父類屬性的初始化;這個調用父類構造器的過程沿著構造器鏈一直往上執行,直到到達構造器鏈的最頂部;當到達了構造器鏈最頂部,且已確保所有執行個體包含的儲存型屬性都已經賦值,這個執行個體的 記憶體被認為已經完全初始化。此時階段 1 完成。階段 2從頂部構造器鏈一直往下,每個構造器鏈中類的指定構造器都有機會進一步定製執行個體。構造器此時可以訪問 self、修改它的屬性並調用執行個體方法等等。 最終,任意構造器鏈中的便利構造器可以有機會定製執行個體和使用 self。
假設要為子類中引入的任意新屬性??供預設值,請遵守以下 2 個規則: 規則 1如果子類沒有定義任何指定構造器,它將自動繼承所有父類的指定構造器。 規則 2如果子類??供了所有父類指定構造器的實現--不管是通過規則 1 繼承過來的,還是通過自 定義實現的--它將自動繼承所有父類的便利構造器。
先將子類中的屬性初始化—————>調用父類的構造器—————>修改子類與父類中屬性的值。
如果你使用閉包來初始化屬性的值,請記住在閉包執行時,執行個體的其它部分都還沒有初始化。這意味著你不能夠在閉包裡訪問其它的屬性,就算這個屬性有預設值也不允許。同樣,你也不能使用隱式的 self 屬性,或者調用其它的執行個體方法。
反初始化函數只適用於類類型。子類繼承了父類的反初始化函數,並且在子類反初始化函數實現的最後,父類的反初始化函 數被自動調用。即使子類沒有??供自己的反初始化函數,父類的反初始化函數也總是被調用。
引用計數只應用在類的執行個體。結構體(Structure)和枚舉類型是實值型別,並非參考型別,不是以引用的方式來儲存和傳遞的。
Swift ??供兩種方法來解決強引用環:弱引用和無主引用。
對於生命週期中引用會變為 nil 的執行個體,使用弱引用;對於初始化時賦值之後引用再也不會賦值為 nil 的執行個體,使用無主引用。
弱引用只能聲明為變數類型,因為運行時它的值可能改變。弱引用絕對不能聲明為常 量。
因為弱引用可以沒有值,所以聲明弱引用的時候必須是可選類型的。在 Swift 語言中,推薦 用可選類型來作為可能沒有值的引用的類型。
無主引用只能定義為非可選類型(non-optional type)。在屬性、變數前添加 unowned關鍵字,可以聲明一個無主引用。
兩個屬性都必須有值,且初始化完成後不能為 nil。這種情境下,則 要一個類用無主引用屬性,另一個類用隱式展開的可選屬性。
自判斷連結(Optional Chaining)是一種可以請求和調用屬性、方法及子指令碼的過程,它的自判斷性體現於請求或調用的目標當前可能為空白(nil)。如果自判斷的目標有值,那麼調用 就會成功;相反,如果選擇的目標為空白(nil),則這種調用將返回空(nil)。多次請求或調用可以被連結在一起形成一個鏈,如果任何一個節點為空白(nil)將導致整個鏈失效。
類型轉換在 Swift 中使用 is 和 as 操作符實現。
Any 和 AnyObject 的轉換Swift 為不確定類型??供了兩種特殊類型別名: 1. AnyObject 可以代表任何 class 類型的執行個體。2. Any 可以表示任何類型,除了方法類型(function types)。
擴充
Swift 中的擴充可以:1. 添加計算型屬性和計算靜態屬性 2. 定義執行個體方法和類型方法3. ??供新的構造器4. 定義下標5. 定義和使用新的巢狀型別6. 使一個已有類型符合??個介面
如果你定義了一個擴充向一個已有類型添加新功能,那麼這個新功能對該類型的所有 已有執行個體中都是可用的,即使它們是在你的這個擴充的前面定義的。
注意:擴充可以添加新的計算屬性,但是不可以添加儲存屬性,也不可以向已有屬性添加屬 性觀測器(property observers)。
Protocol(協議)用於統一方法和屬性的名稱,而不實現任何功能。協議能夠被類,枚舉,結 構體實現,滿足協議要求的類,枚舉,結構體被稱為協議的遵循者。
用類來實現協議時,使用 class 關鍵字來表示該屬性為類成員;用結構體或枚舉實現協議時, 則使用 static 關鍵字來表示:
協議方法支援變長參數(variadic parameter),不支援預設參數(default parameter)。
用 class 實現協議中的 mutating 方法時,不用寫 mutating 關鍵字;用結構體,枚舉實現協議中的 mutating 方法時,必須寫 mutating 關鍵字。
協議本身不實現任何功能,但你可以將它當做類型來使用。使用情境:1. 作為函數,方法或構造器中的參數類型,傳回值類型2. 作為常量,變數,屬性的類型3. 作為數組,字典或其他容器中的元素類型
委託是一種設計模式,它允許類或結構體將一些需要它們負責的功能交由(委託)給其他的類 型。委託模式的實現很簡單: 定義協議來封裝那些需要被委託的函數和方法, 使其遵循者擁有這些被委託的函數和方法。 委託模式可以用來響應特定的動作或接收外部資料源??供的資料,而無需要知道外部資料源的類型。
當一個類型已經實現了協議中的所有要求,卻沒有聲明時,可以通過擴充來補充協議聲明:
協議合成並不會產生一個新協議類型,而是將多個協議合成為一個臨時的協議,超出 範圍後立即失效。
@objc 用來表示協議是可選的,也可以用來表示暴露給 Objective-C 的代碼,此外,@objc 型協議只對類有效,因此只能在類中檢查協議的一致性
注意:可選協議只能在含有@objc 首碼的協議中生效。且@objc 的協議只能被類遵循。
swapTwoValues 函數和 Stack 類型可以作用於任何類型,不過,有的時候對使用在泛型函 數和泛型型別上的類型強制限制式為??種特定類型是非常有用的。類型約束指定了一個必須 繼承自指定類的型別參數,或者遵循一個特定的協議或協議構成。
swift 閱讀記錄