1 什么是some
在今年的WWDC上,蘋果新推出的SwiftUI中出現了新的關鍵字some
這里的some其實就是和一個稱為opaque(不透明)類型有關,在返回類型前面加上一些關鍵字表示返回類型是不透明的,不透明類型通常被稱為反向泛型類型。
2 什么是泛型和some的作用
當你想聲明使用多種類型的函數時,泛型類型基本上就是一個占位符,舉個例子,max函數,取出兩個數字的最大值,我們使用到了未知類型T
這里如果要比較大小,必須限定T支持比較操作,所以限定約束條件T:Comparable
在使用的時候編譯器可以通過函數參數來推斷T是什么類型
我們定義一個SurpriseEgg協議,具有關聯類型ContentType,并且創建改類型的具體類型。
現在假如我們實現一個方法去抽取蛋,但是我們不知道具體是那種蛋,因為他可能是Puzzle、ToyEgg和FigureEgg中任何一種,因為他肯定是某種彩蛋(SupriseEgg)
這不會在?Swift中編譯,因為swift不能把帶有關聯類型的協議類型作為返回類型。
這個時候就可以使用some關鍵字
添加這個關鍵字代表,你和編譯器都確定這個函數總會返回一個特定的具體類型-只是你不知道是哪一種
3 這樣做有什么用處?
使用不透明類型有兩個很重要作用
1 返回關聯類型的協議類型
現在我們可以從函數返回一個protocol,protocol中帶有一個associated 類型,在以前的版本中,swift不允許我們把具有關聯類型的協議作為返回類型。
這種寫法是可以的,
帶有關聯類型的不可以作為返回類型
協議中使用Self關鍵字的也是不可以作為返回類型
都需要增加some關鍵字
2?SwiftUI中的不透明類型
SwiftUI的強大之處在于它的可組合性。通常,您可以使用堆棧視圖和其他容器(如列表)從其他視圖組成布局。這些容器都是通用類型,每次添加,刪除,移動或替換視圖時,它們的具體類型都會更改。例如,讓我們看看以下簡單的自定義視圖:
這個類型some View 可以被推斷未?VStack<TupleView<(Text, Image)>>
如果沒有some關鍵字,我們必須這樣寫
如果我們需要加一個文本Text,那就需要改寫返回值
這已經很煩人了。但最有可能的是,我們將使用多個容器。我們可能希望將堆棧嵌套在另一個堆棧中,也可能是列表中的其他堆棧。突然,我們身體的具體類型看起來像這樣
List <Never,TupleView <(HStack <TupleView <(VStack <TupleView <(Text,Text)>>,Text)>>,HStack <TupleView <(VStack <TupleView <(Text,Text)>>,Text)>> )>>
你可能會同意這沒有任何意義。更改層次結構中的單個視圖時更新此類型非常繁瑣。最重要的是,類型根本不可讀。我們的思想無法在合理的時間內處理它,我們關心的實際上就是body返回some?View。
這正是Apple為什么在他們的教程中使用不透明視圖類型以及為什么你應該總是這樣做的原因: