我已經通過了Apple開發人員網站上的Swift教程,但我不理解泛型的概念。有人能夠用簡單的方式解釋它嗎?例如:Swift中的泛型2.0
func swapTwoValues<T>(inout a: T, inout b: T) {
let temporaryA = a
a = b
b = temporaryA
}
我已經通過了Apple開發人員網站上的Swift教程,但我不理解泛型的概念。有人能夠用簡單的方式解釋它嗎?例如:Swift中的泛型2.0
func swapTwoValues<T>(inout a: T, inout b: T) {
let temporaryA = a
a = b
b = temporaryA
}
如果沒有你給的例子使用泛型一個功能,你必須重載swapTwoValues
你想每一個類型互換。例如:
func swapTwoValues(inout a: Int, inout b: Int) {
let temp = a
a = b
b = temp
}
func swapTwoValues(inout a: String, inout b: String) {
let temp = a
a = b
b = temp
}
// Many more swapTwoValues functions...
上述函數之間唯一不同的是它們接受的類型;每個內部的代碼都完全相同。因此,最好寫一個可以採用任何類型的通用函數。
請務必注意,您不能用Any
替代T
。不能保證a
和b
將是同一類型 - 例如,您不能交換Int
和String
。
本質上,它只是意味着它不是類型特定的。您可以使用T
,只是寫的,而不是寫很多功能爲每種類型的Int
,Double
,Float
,String
等
在你的例子中,T表示一個Type。並且一旦設置該類型對於整個功能是一致的。
func swapTwoValues<T>(inout a: T, inout b: T) {
let temporaryA = a
a = b
b = temporaryA
}
如果T是一個Int在一個參數的情況下,那麼它也必須是一個Int在參數b的情況下。作爲該功能的正常使用證明:
var valueA = 2
var valueB = 4
swapTwoValues(&valueA, b: &valueB)
valueA // 4
valueB // 2
我們不能換一個String類型爲int的例如甚至是詮釋了雙,但只要類型相同,則該泛型方法將採取任何類型,因爲它在所有其他方面都沒有限制。
var valueA = "Hello"
var valueB = "Swift"
swapTwoValues(&valueA, b: &valueB)
valueA // "Swift"
valueB // "Hello"
但這並不意味着多種類型被排除在泛型函數之外。您只需指定一個不同的字母來表示不同的類型(使用的字母無關緊要,因爲它是Type的第一個字母,所以簡單地使用T,但沒有理由不能用Q替換,或者任何其他盤符):
func swapTwoValues<T,S>(inout a: T, inout b: T, inout c: S, inout d: S) {
let temporaryA = a
a = b
b = temporaryA
let temporaryC = c
c = d
d = temporaryC
}
var valueA = 2
var valueB = 4
var valueC = "Hello"
var valueD = "Swift"
swapTwoValues(&valueA, b: &valueB, c:&valueC, d:&valueD)
valueA // 4
valueB // 2
valueC // "Swift"
valueD // "Hello"
注:我們還不能換一件T爲S,因爲斯威夫特是一個強類型語言,我們也沒有安慰他們是相同的。
當涉及約束泛型類型的協議時,它變得更有趣。在這裏,我與UnsignedIntegerType這樣做:
func swapTwoValues<T: UnsignedIntegerType>(inout a: T, inout b: T) {
let temporaryA = a
a = b
b = temporaryA
}
var valueA:UInt = 10
var valueB:UInt = 11
swapTwoValues(&valueA, b: &valueB)
現在只有類型如uint,UINT8,UInt32的,等是可以接受的,所有其他值都將被拒絕,並創建一個錯誤。
注意:使用協議約束類型的原因是爲了保證某些方法能夠正常工作。例如,如果需要通用函數來創建新的類型實例,那麼它必須採用init方法採用協議。 (您可以檢查Apple文檔中每種類型的協議採用情況。)
我們可以更進一步,使用where
關鍵字來確定包含一個泛型集合中的類型:
func swapTwoValues<T: CollectionType where T.Generator.Element: UnsignedIntegerType>(inout a: T, inout b: T) {
let temporaryA = a
a = b
b = temporaryA
}
var valueA:[UInt] = [10,12,4]
var valueB:[UInt] = [11,45,67]
swapTwoValues(&valueA, b: &valueB)
valueA // [11, 45, 67]
valueB // [10, 12, 4]
或者不喜歡的東西的支票,第二類是相當於元素的集合中的類型使用==
:
func swapTwoValues<T: CollectionType, S where S == T.Generator.Element>(inout a: T, inout b: T, inout c: S, inout d: S) {
let temporaryA = a
a = b
b = temporaryA
let temporaryC = c
c = d
d = temporaryC
}
延伸閱讀:事情變得更加有趣與protocol extensions in Swift 2因爲現在通用的功能,可以採取類型方法的特點,這使得它們遠M礦石可發現。
偉大的問題,你應該考慮選擇一個這個問題的答案,如果一個滿足你的問題!這可以提高您的帖子的質量,從而使社區受益。 –