1. 程式人生 > >Swift4 中的泛型約束

Swift4 中的泛型約束

源連結:http://www.cocoachina.com/ios/20171025/20903.html

範型可以說是 Swift 跟 OC 相比最大的優勢了。通過給像集合這類東西關聯泛型, 可以寫出更可預測並且更安全的程式碼。在 Swift4 中型別約束更為強大, 它能夠讓我們更能夠輕而易舉的做很多事情。即使是通用程式碼, 也能充分的利用 Swift 的型別系統。

例1:

首先我們來看看一個簡單的例子。比如說給一個數字數字求和。我們可能會些這樣的程式碼:

123456// 在這段程式碼中, 我們定義了一個方法, 接受一個 Int 陣列作為引數, 在方法內部使用高階函式 reduce 最後返回這個結果。func sum(_ numbers: [Int]) -> Int {
return numbers.reduce(0, +)}let array = [1,2,3,4,5]sum(array) // 15

使用泛型約束, 我們可以這樣來實現這個需求:

1234567// 在這段程式碼中, 我們給 Array 添加了型別約束的 Extension。當陣列的 Element 遵守了 Numeric 協議的時候, Array 就擁有 sum 這個方法。extension Array where Element: Numeric {func sum() -> Element {return reduce(0, +)}}array.sum() // 15

兩者相比, 使用泛型約束最大的優勢是使用擴充套件, 能夠讓這個功能跟呼叫者更緊密。比較一下:

12let sum = sum(array)let sum = array.sum()

在 OC 裡面, 可能有些同學會寫一個 XXXTool 之類的類, 來封裝這種型別的功能。 或者是直接寫成 C 的函式。但是不論怎麼寫, 這樣貌似都不是特別的 OOP。或者OC 還可以直接給 NSArray 加一個 category, 然後再實現相似的功能。但是, 這樣做不就等於所有的 array 都具有這個功能了嗎?

例2

再來看這樣的需求: 計算某個包含字串集合中有多少個單詞。我們可以通過給集合新增一個擴充套件輕鬆的完成這件事情。給 Collection 新增一個約束, 限制集合中的 Element 是 String型別:

12345678910extension Collection where Element == String {func countWords() -> Int {return reduce(0) {let components = $1.components(separatedBy: .whitespacesAndNewlines)return $0 + components.count}}}let array2 = ["sunny","cloudy","apple orange"]array2.countWords() // 4

還有一個很酷的做法是約束集合型別中的 Element 是 Closure:

123456789101112131415extension Sequence where Element ==  () -> Void {func callAll() {forEach { $0() }}}let closure1 = {print("1")}let closure2 = {print("2")}let array3 = [closure1, closure2]array3.callAll() //1//2

例3

還有一個很好用的特性是使用協議定義 API 的時候。這幾乎是寫可測試程式碼以及功能解耦的最佳實踐了。需要注意的是, 在需要靈活使用巢狀型別的時候, 這可能會有點麻煩。

看例子吧!我們經常都想要定義一些通用的 API, 來管理程式中的各種 model。這時候肯定會想要定義一個協議:

123

相關推薦

Swift4 約束

源連結:http://www.cocoachina.com/ios/20171025/20903.html範型可以說是 Swift 跟 OC 相比最大的優勢了。通過給像集合這類東西關聯泛型, 可以寫出更可預測並且更安全的程式碼。在 Swift4 中型別約束更為強大, 它能夠讓

關於C#參數約束(where T : class)

name ica title logic .get ted inter host ase .NET支持的類型參數約束有以下五種:where T : struct | T必須是一個結構類型where T :

C#的where約束的new()

1.在MSDN上面對new()解釋說到是where字句的建構函式約束,帶有new()約束的任何型別都必須有可訪問的無參建構函式,正常來說C#建立的類預設都有一個無參的建構函式,即使你沒有寫,但是如果你寫了一個有引數的建構函式後,那麼就沒有預設無參的那個了,就需要自己手動

C#約束

bstr 部分 name 一個 參數 list 多個 哈哈 override 本文將對各類泛型約束做一個簡單的總結。 文章一開始,給出演示代碼底稿(在此基礎上修改,演示,說明。) class MyList<T> { List<T> list

約束

pac 指定 泛型 () 使用 實現 new spa 包括 約束說明 T:struct 類型參數必須是值類型。可以指定除 Nullable 以外的任何值類型。 T:class 類型參數必須是引用類型,包括任何類、接口、委托或數組類型。 T:n

Java通配符的一點概念

for name 安全 msg simple clist getc 保持 spa 以List<T>為例,通常如果我們想在List中存儲某種類型的數據,我們會用下面的語法進行聲明和使用: 1 List<String> allMsg =

JavaClass<T>、T與Class<?>

arraylist new 對象類型 創建 集合 spa div get 裏的 一.區別 單獨的T 代表一個類型 ,而 Class<T>代表這個類型所對應的類, Class<?>表示類型不確定的類 E - Element (在集合中使用,因為集合

Java的約束和限制

實例 == -h 不同 java異常 轉換 component 參數 測試 不能用基本類型實例化類型參數 不能用類型參數代替基本類型:例如,沒有Pair<double>,只有Pair<Double>,其原因是類型擦除。擦除之後,Pair類含有O

JavaT和Class<T>以及Class<?>的理解(轉)

tcl ota 特定 類型 基本 ext pla enum extend 註意:class是java的關鍵字, 在聲明Java類時使用; Class類的實例表示Java應用運行時的類(class ans enum)或接口(interface and annotatio

Java得到T.class

[] 大括號 alt 泛型 tcl target get gen ava 例子: public class Test<T> { public Class<T> getTClass() { return (Class&

C#約束 (轉載)

六種型別的約束: T:結構 型別引數必須是值型別。可以指定除 Nullable 以外的任何值型別。有關更多資訊,請參見使用可空型別(C# 程式設計指南)。 T:類 型別引數必須是引用型別,包括任何類、介面、委託或陣列型別。

教你如何攻克Kotlin變的難點(上篇)

簡述: Kotlin中泛型相關的文章也幾乎接近尾聲,但到後面也是泛型的難點和重點。相信有很多初學者對Kotlin中的泛型型變都是一知半解,比如我剛開始接觸就是一臉懵逼,概念太多了,而且每個概念和後面都是相關的,只要前面有一個地方未理解後面的難點更是越來越看不懂。Kotlin的泛型比Java中的泛型多了一些新的

Java的使用(日常總結)

一、什麼是泛型 泛型,即“引數化型別”。就是將型別由原來的具體的型別引數化,類似於方法中的變數引數,此時型別也定義成引數形式(可以稱之為型別形參),然後在使用/呼叫時傳入具體的型別(型別實參)。 例子: public static void main(String[] args) {

教你如何攻克Kotlin變的難點(下篇)

簡述: 前幾天我們一起為Kotlin中的泛型型變做了一個很好的鋪墊,深入分析下型別和類,子型別和子類之間的關係、什麼是子型別化關係以及型變存在的意義。那麼今天將會講點更刺激的東西,也就是Kotlin泛型型變中最為難理解的地方,那就是Kotlin中的協變、逆變、不變。雖然很難理解,但是有了上篇文章基礎教你如何攻

教你如何攻克Kotlin變的難點(應用篇)

簡述: 這是泛型型變最後一篇文章了,也是泛型介紹的最後一篇文章。順便再扯點別的,上週去北京參加了JetBrains 2018開發者日,主要是參加Kotlin專場。個人感覺收穫還是挺多的,bennyHuo和彥偉老師精彩演講確實傳遞很多幹貨啊,當然還有Hali佈道師大佬帶來了的Kotlin1

教你如何攻克Kotlin變的難點(實踐篇)

簡述: 這是泛型型變最後一篇文章了,也是泛型介紹的最後一篇文章。順便再扯點別的,上週去北京參加了JetBrains 2018開發者日,主要是參加Kotlin專場。個人感覺收穫還是挺多的,bennyHuo和彥偉老師精彩演講確實傳遞很多幹貨啊,當然還有Hali佈道師大佬帶來了的Kotlin1.3版本的新特性以及G

scala和隱式轉化

隱式轉化 邊寫邊譯模式中:   new Person[Int](15,18).max() class Data(number: Int){ def show(): Int ={ print("1"+" "+number) 2 } } implicit def show(n

Java相關問題

泛型的概念          java 泛型是java SE 1.5的新特性,泛型的本質是引數化型別,也就是說所操作的資料型別被指定為一個引數。這種引數型別可以用在類、介面和方法的建立中,分別稱為泛型

一步步學spark之一scala高階特性類與函式3.6

一步步學spark之一scala高階特性中泛型類與泛型函式 泛型類中的泛型是包容具體型別變換的,對這些具體不同的型別,泛型類根據型別進行統一的操作,很多時候泛型類就相當於模板。 泛型定義一個泛型引數 兩個泛型引數 定義空的Map 返回的型別中是

約束-swift

1、泛型定義本體有參量型別約束; 2、泛型擴充套件對參量型別約束; 3、函式參量約束;   泛型型別的訪問控制: 1、與型別無關的通用函式,泛型的任何例項都可以訪問; 2、與型別有關的函式(通過擴充套件約束實現),只有特定型別例項化的泛型例項才能訪問;   由此得出結論: