成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Emptiness空值語義

移動開發 iOS
Swift 比起 C 語言已經修改了很多規則了. 例如, switch 里不需要 break 了, 甚至可以使用 fallthrough 來把幾個 case 連接起來. 沒有了 ++ 操作符, 它是那么的讓人迷惑, 多余, 并且沒了它語言會變得更好。

[[181591]]

如果 Swift 里的 array 數組不能為空?

仔細想想: 如果 Swift 已經設計了非空的數組了. 但這會讓人很煩對吧? 什么語言有非空的數組?

然而, Swift 比起 C 語言已經修改了很多規則了. 例如, switch 里不需要 break 了, 甚至可以使用 fallthrough 來把幾個 case 連接起來. 沒有了 ++ 操作符, 它是那么的讓人迷惑, 多余, 并且沒了它語言會變得更好.

還有一點 Swift 跟 C 不一樣, Swift 需要顯式地聲明可空性. Swift 讓你使用 Optional 類型, 向類型系統指定某個值是否可能有空. 你可以說你有一個 controller, 或者可能有一個 controller 也可能沒有. 類型系統可以在所有地方都檢查一遍, 保證這個值在被需要使用時不會為空.

<!--more-->

Doubly Empty

當 Optional 和 Array 產生交匯時, 你會有兩種方式去描述空值: nil 或者是空數組.

這可能會有點繞, 例如, 當你檢查一個數組是否為 nil 或者為空數組的時候. 例如, 你想要更好地使用 Swift 里的 optional chaining 的時候, optionalArray?.isEmpty 卻返回了一個 Optional<Bool>, 一個本質上很讓人迷惑的類型. 如果在 if 判斷句里使用了這一描述的話, 編譯器會拋出一個編譯錯誤, 因為這是一個 Optional 的布爾值.

optionalArray == [] 會被編譯, 但會在數組為 nil 的時候返回 false, 而這并不是我們想要的行為. 你可以有這么幾種方式達到目的, 但不多: 

  1. if optionalArray == nil || optionalArray == [] { 
  2.  
  3. if let array = optionalArray, array.isEmpty { 
  4.  
  5. if (optionalArray ?? []).isEmpty { 
  6.  
  7. if optionalArray?.isEmpty != false { 
  8.  
  9. if optionalArray?.isEmpty ?? false {  

最簡單的方法是記住不要使用 Optional 的數組. 我一直嚴格遵守著這個規則, 保證不會把不同類型的"空值"混合到一起. 對于別的"可空"類型我也是這么做的 - 字典, 字符串, 布爾值和一些別的類型. 不得不去檢查兩種類型的控制檢查是我最不想做的事情.

遵守這個規則很容易, 例如說一個類里的屬性, 但不可能在所有情況下都遵守這個規則. 例如, 從一個 Optional 的實例那里獲取一個數組屬性就會成為一個 Optional 的數組.

  1. let wheels = optionalCar?.wheels // 結果是 [Wheel]? 

從一個字典里面去獲取數組也是一樣.

  1. let wheels = dictionary["wheels"as? [Wheel] 

你不得不去在每一個語句后面都加上 ?? [].

我們剛擺脫了無法分辨 controller 和可空 controller 的困境. 獲得了簡化語句, 減少錯誤和可聲明的能力. 現在卻又遇上了這種窘境.

如果一個數組不能為空, 那 Optional 的數組就代表了空數組, 非 Optional 的數組則總會包含至少一個值. 就不可能同時出現兩種語義上的空值了, 而任何采用了別的語義的代碼都不會通過編譯.

Modeling

非空數組對于建立模型也很有用處. 告訴類型系統一個給定的數組永遠不可能為空有時候很有用. 例如, 也許你的 User 類有許多個郵箱, 但如果 user 沒有郵箱的話則不應該被驗證. 可以讓類型系統接收這樣的描述是一件很棒的時期, 但現在我們做不到. 其他例子:

  • 一個 Country 國家必須有至少一座 City 城市.
  • 一張 Album 專輯必須有至少一首 Song 歌.
  • 一棟 Building 樓必須有至少一層 Floor.

這樣的例子一大堆.

如果一個數組類型不能為空, 這些關系和約束全部都可以在類型系統里展現出來, 并且你不能刪掉數組里的***一個元素.

Expressions 語句表述

隨著 Optional 類型的出現, 許多表述都被簡化 當你知道一個類型永遠不可能為空的時候, 你可以跳過空值檢查, 用一個更直觀的方式去操作它. 對于非空的數組也是一樣的. 現在, Collection 協議的方法, 例如 first, last, max 和 min 都會返回 Optional, 只是為了處理數組為空的情況.

有許多的情況下數組都不會為空, 但每當我使用諸如 first 之類的方法的時候, 我還是不得不去做防御, 僅僅只是為了告訴類型系統它不為空.

如果數組不可能為空的話, 這些方法都可以返回一個非空值, 使用這些語句都會變得更容易. 空數組可以通過 optional chaining 來調用這些方法, 而返回值也會是 Optional.

Appending 插入

如果數組不可能為空, 那往非空數組里插入內容就可以很正常地工作. 但往一個可空數組里插入值就會是一場災難.

  1. var emptiableArray = //... 
  2. emptiableArray == nil 
  3.     ? emptiableArray = [newItem] 
  4.     : emptiableArray?.append(newItem)  

這很讓人心煩, 但好消息是, 在 Swift 3.1 里, 我們可以給特定類型的泛型類型添加 extension. 那么, 我們就可以往 Optional 的 Array類型添加方法(在這之前, 你只能給使用了遵守了協議的某個類型添加 extension)

  1. extension Optional<Array<Element>> { 
  2.     func append(_ element: Element) { 
  3.         switch self { 
  4.         case .some(array): 
  5.             array.append(element) 
  6.         case .none: 
  7.             self = [element] 
  8.         } 
  9.     } 
  10.  

現在我們可以像之前那樣暢通無阻的操作了.

Without Loss Of Generality

我們再進一步, 如果數組的泛型參數包含了數組長度呢? 例如, 給 Array<of: 4, element: String> 插入一個值的時候就會返回一個Array<of: 5, element: String. 這個概念被稱為 dependent types, 并且在一些實驗性的帶有更先進的類型系統的語言里已經實現了, 例如 Coq, Agda 和 Idris. Oisín 討論過如何在 Swift 里實現一樣的東西出來.

雖然這些東西非常好玩, 但也有一點不切實際. 你想想, 這意味著你不能在類里保存數組了, 除非你知道這個數組的長度永遠不會被改變. 在很多情況下, 你不可能知道編譯時會有多少個對象從 API 和數據庫里被返回

簡單的鑒別 空/非空 有很明確的現實意義, 并且也會簡化 Swift 很多內部運作方式.

NonEmptyArray

This blog post is mostly a thought experiment. But it’s also a regular experiment. To that end, I built a non-empty array type. You can find it on GitHub here. It acts just like an array, but it isn’t emptiable. It conforms to Sequence, Collection, and has == and!= methods.

這篇文章更像是一個 Idea 的嘗試. 但這也只是一個常規嘗試. 作為結尾, 我建立了一個非空數組類型. 你可以到這里看源碼, 運作起來就像一個數組, 但不為空. 遵守 Sequence, Collection 協議并且有 == 和 != 方法.

由于 Swift 的類型系統有一部分我沒能完全理解, 但盡管如此, 你還是可以重寫協議(例如 Collection)里的方法(例如 first), 然后把Element? 修改了 Element, Swift 會在調用時爭產工作, 并且使用更加明確的類型, Element. 這意味著 NonEmptyArray 會在 first,last, max 和 min 里返回 non-optional, 雖然 Collection 里它們被定義為 Optional, repo 里的測試有斷言來判斷這個.

擁有一個絕對不為空的數組會有很多有趣的事情發生. 插入還好, 但刪除元素的方法會帶來更多問題. 我把這個方法標記為 throws, 但經過更多思考之后, 這也許不是一種正確地做法. 畢竟, Swift 原生的數組刪除元素時也會產生問題, 只是它比起 NonEmptyArray 可以一個以上的元素. Swift 的數組會在嘗試刪除空數組的元素時調用 fatalError, 所以也許這才是正確地做法.

我很期待可以把 NonEmptyArray 拆分成幾個提案, 看看失去 Swift 原生數組類型的語法糖是否值得, 去換取返回 non-optional 的方法.

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2009-08-25 17:52:01

C#可空值類型

2011-02-24 13:55:12

SQL Server可空字段非空值

2018-02-27 15:41:27

IOT語義操作性

2025-03-10 08:30:00

2025-02-27 09:39:56

JavaJava 8對象

2010-07-06 10:25:16

SQL Server空

2023-05-18 13:47:10

語義Web信任

2013-01-30 16:52:06

2020-10-18 10:47:22

空值合并運算符 '??

2020-08-11 11:00:16

左值引用右值引用移動語義

2024-09-10 09:03:54

微軟TypeScript

2009-07-14 13:38:41

語義化HTMLHTML結構

2023-08-18 06:51:13

2024-01-10 08:08:25

Python空值校驗開發

2018-07-02 09:14:24

神州泰岳

2011-03-07 10:10:35

MySQL處理空值

2020-08-18 22:20:49

vue.jsnullclass

2024-09-12 09:38:13

2010-06-23 17:42:28

Linux Bison

2024-09-29 00:00:02

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄色网络在线观看 | 日韩一区精品 | 伊人超碰在线 | 成人一区二区三区在线 | 看一级毛片| 免费观看毛片 | 国产三级 | 国产99久久 | 91香蕉嫩草 | 一区二区三区久久 | 精品国产乱码久久久久久闺蜜 | 久久久2o19精品 | 久久99国产精品久久99果冻传媒 | 欧美高清dvd| 国产精品美女久久久久aⅴ国产馆 | 国产精品视频一二三区 | 久久久www成人免费无遮挡大片 | 色噜噜狠狠色综合中国 | 91精品国产一区二区三区动漫 | 精品日韩 | 成人久久久久 | 久久久av | 天堂亚洲 | 国产91久久久久久 | 精品不卡| 在线观看特色大片免费网站 | 蜜桃精品噜噜噜成人av | 孕妇一级毛片 | 亚洲久久一区 | 久久精品国产一区二区电影 | 蜜臀91视频 | 欧美日韩久久 | 国产午夜精品一区二区三区嫩草 | 国产精品久久久久久久久 | 美女一级a毛片免费观看97 | 真人女人一级毛片免费播放 | 狠狠干av| 亚洲激情视频在线 | 国产一区二区视频在线观看 | 欧美久久久久久久久中文字幕 | 国产伦精品 |