<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
Swift中引入了可選項(Optional)的概念是為了解決在程式碼中對於某些變數或常數可能為nil的情況進行處理,從而減少了程式中的不確定性,使得程式更加穩定和安全。
在Swift中,可選項的型別是使用?來表示的,例如String?即為一個可選的字串型別,表示這個變數或常數可能為nil。而對於不可選項,則直接使用相應型別的名稱,例如String表示一個非可選的字串型別。
var str: String = nil var str1: String? = nil 複製程式碼
Optional實際上是Swift語言中的一種列舉型別。在Swift中宣告Optional型別時,編譯器會自動將其轉換成對應的列舉型別,例如:
var optionalValue: Int? = 10 // 等價於: enum Optional<Int> { case none case some(Int) } var optionalValue: Optional<Int> = .some(10) 複製程式碼
在上面的程式碼中,我們宣告了一個Optional型別的變數optionalValue,並將其初始化為10。實際上,編譯器會自動將其轉換為對應的列舉型別,即Optional列舉型別的.some(Int),其中的Int就是我們所宣告的可選型別的關聯值。
當我們在使用Optional型別的變數時,可以通過判斷其列舉值是.none還是.some來確定它是否為nil。如果是.none,表示該Optional值為空;如果是.some,就可以通過存取其關聯值獲取具體的數值。
Optional的原始碼實現為:
@frozen public enum Optional<Wrapped> : ExpressibleByNilLiteral { case none case some(Wrapped) } 複製程式碼
使用 if let 或者 guard let 語句來判斷 Optional 變數是否有值,如果有值則解包,並將其賦值給一個非可選型別的變數。
var optionalValue: Int? = 10 // 可選項繫結 if let value = optionalValue { print("Optional value is (value)") } else { print("Optional value is nil") } 複製程式碼
可選項繫結語句有兩個分支:if分支和else分支。如果 optionalValue 有值,if 分支就會被執行,unwrappedValue 就會被賦值為 optionalValue 的值。否則,執行 else 分支。
使用!來獲取一個不存在的可選值會導致執行錯誤,在使用!強制展開之前必須保證可選項中包含一個非nil的值
var optionalValue: Int? = 10 let nonOptionalValue = optionalValue! // 解包optionalValue值 print(nonOptionalValue) // 輸出:10 複製程式碼
需要注意的是,如果 Optional 型別的值為 nil,使用強制解包方式解包時,會導致執行時錯誤 (Runtime Error)。
在定義 Optional 型別變數時使用 ! 操作符,標明該變數可以被隱式解包。用於在一些情況下,我們可以確定該 Optional 變數繫結後不會為 nil,可以快捷的解包而不用每次都使用 ! 或者 if let 進行解包。
var optionalValue: Int! = 10 let nonOptionalValue = optionalValue // 隱式解包 print(nonOptionalValue) // 輸出:10 複製程式碼
需要注意的是,隱式解包的 Optional 如果 nil 的話,會導致 runtime error,所以使用隱式解包 Optional 需要確保其一直有值,否則還是需要檢查其非 nil 後再操作。
總的來說,我們應該儘量避免使用強制解包,而是通過可選項繫結來處理 Optional 型別的值,在需要使用隱式解包的情況下,也要確保其可靠性和穩定性,儘量減少出現執行時錯誤的概率。
是一種在 Optional 型別值上進行操作的方式,可以將多個 Optional 值的處理放在一起,並在任何一個 Optional 值為 nil 的時刻停止處理。
通過在 Optional 型別值後面跟上問號 ?,我們就可以使用可選鏈來存取該 Optional 物件的屬性和方法。
class Person { var name: String var father: Person? init(name: String, father: Person?) { self.name = name self.father = father } } let father = Person(name: "Father", father: nil) let son = Person(name: "Son", father: father) // 可選鏈呼叫屬性 if let fatherName = son.father?.name { print("Father's name is (fatherName)") // 輸出:Father's name is Father } else { print("Son without father") } // 可選鏈呼叫方法 if let count = son.father?.name.count { print("Father's name has (count) characters") // 輸出:Father's name has 6 characters } else { print("Son without father") } 複製程式碼
在上面的程式碼中,我們定義了一個 Person 類,並初始化了一個包含父親(father)的兒子(son)物件。其中,父親物件的father屬性為nil。我們使用問號 ? 來標記 father 物件為 Optional 型別,以避免存取 nil 物件時的執行時錯誤。
需要注意的是,如果一個 Optional 型別的屬性通過可選鏈呼叫後,返回值不是 Optional 型別,那麼在可選鏈呼叫後,就不再需要加問號 ? 標記其為 Optional 型別了。
class Person { var name: String var age: Int? init(name: String, age: Int?) { self.name = name self.age = age } func printInfo() { print("(name), (age ?? 0) years old") } } let person = Person(name: "Tom", age: nil) // 可選鏈呼叫方法後,返回值不再是 Optional 型別 let succeed = person.printInfo() // 輸出:Tom, 0 years old 複製程式碼
在上面的程式碼中,我們定義了一個 Person 類,並初始化了一個包含年齡(age)的人(person)物件。在可選鏈呼叫物件的方法——printInfo() 方法後,因為該方法返回值不是 Optional 型別,所以 returnedValue 就不再需要加問號 ? 標記其為 Optional 型別了。
將一個 Optional 型別的值作為另一個 Optional 型別的值的成員,形成巢狀的 Optional 型別。
var optionalValue: Int? = 10 var nestedOptionalValue: Int?? = optionalValue 複製程式碼
在上面的程式碼中,我們定義了一個 Optional 型別的變數 optionalValue,並將其賦值為整型變數 10。然後,我們將 optionalValue 賦值給了另一個 Optional 型別的變數 nestedOptionalValue,形成了一個巢狀的 Optional 型別。
在處理巢狀的 Optional 型別時,我們需要特別小心,因為它們的使用很容易造成邏輯上的混淆和錯誤。為了解決這個問題,我們可以使用 Optional Binding 或者 ?? 操作符(空合併運運算元)來降低 Optional 巢狀的複雜度。
var optionalValue: Int? = 10 var nestedOptionalValue: Int?? = optionalValue // 雙重可選項繫結 if let nestedValue = nestedOptionalValue, let value = nestedValue { print(value) // 輸出:10 } else { print("Optional is nil") } // 空合併運運算元 let nonOptionalValue = nestedOptionalValue ?? 0 print(nonOptionalValue) // 輸出:Optional(10) 複製程式碼
在上面的程式碼中,我們使用了雙重可選項繫結來判斷 nestedOptionalValue 是否可繫結,以及其巢狀的 Optional 值是否可繫結,並將該值賦值給變數 value,以避免 Optional 值的巢狀。另外,我們還可以使用 ?? 操作符(空合併運運算元)來對巢狀的 Optional 值進行預設取值的操作。
需要注意的是,雖然我們可以使用 ?? 操作符來降低 Optional 值的巢狀,但在具體的實際應用中,我們應該在設計時儘量避免 Optional 值的巢狀,以便程式碼的可讀性和維護性。如果對於某個變數來說,它的值可能為空,我們可以考慮使用預設值或者定義一個預設值的 Optional 值來代替巢狀的 Optional 型別。
學習 Swift,勿忘初心,方得始終。但要陷入困境時,也不要忘了最初的夢想和時代所需要的技能。
以上就是Swift中的可選項Optional解包方式實現原理的詳細內容,更多關於Swift可選項Optional的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45