//: Playground - noun: a place where people can play
import UIKit
// # 泛型解決的問題
/*
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
print("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
*/
// # 泛型函數(shù)
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// trick: swap(_:_:)Swift庫已實現(xiàn)
// # 類型形式參數(shù)
// 類型形式參數(shù)指定并且命名一個占位符類型,緊挨著寫在函數(shù)名后面的一對尖括號里(比如 <T> )
// # 命名類型形式參數(shù)
// 用大寫駝峰命名法,表明是一個占位符
// # 泛型類型
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
init() {
// just do nothing here
}
init(items: [Element]) {
self.items = items
}
}
var stackOfStrings = Stack<String>()
stackOfStrings.push("uno")
stackOfStrings.push("dos")
stackOfStrings.push("tres")
stackOfStrings.push("cuatro")
let fromTheTop = stackOfStrings.pop()
var stackOfInts = Stack(items: [1, 2, 7]) // '<Int>' can be inferred so is omittd.
// *** 泛型的類可以被繼承為非泛型
let view = UIView()
let label = UILabel()
let topConstraint = label.topAnchor.constraint(equalTo: view.topAnchor)
// YAnchor is a subclass of anchor. Anchor is a generic class.
// 參見泛型1.playground
// # 擴展一個泛型類型
extension Stack {
var topItem: Element? {
return items.isEmpty ? nil : items[items.count - 1]
}
}
if let topItem = stackOfStrings.topItem {
print("The top item on the stack is \(topItem).")
}
// # 類型約束
// For example, Hashable: a type that provides an integer hash value.
/*
func findIndex(ofString valueToFind: String, in array: [String]) -> Int? {
// trick: array.enumerated() 返回了一個元組的數(shù)組,用for-in提取每個元素(n, x)
// 若為數(shù)組,n是從零開始的序列,x是對應(yīng)的元素
// 若為字符串,n是從零開始的序列,x是對應(yīng)的字符
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
let strings = ["cat", "dog", "llama", "parakeet", "terrapin"]
if let foundIndex = findIndex(ofString: "llama", in: strings) {
print("The index of llama is \(foundIndex)")
}
*/
func findIndex<T: Equatable>(of valueToFind: T, in array:[T]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
let doubleIndex = findIndex(of: 9.3, in: [3.3424, 0.1, 0.25])
let stringIndex = findIndex(of: "Andrea", in: ["Mike", "Malcolm", "Andrea"])
// # 關(guān)聯(lián)類型
protocol Container {
associatedtype ItemType // ItemType 是一個占位符
mutating func append(_ item: ItemType)
var count: Int { get }
// trick: 下標在協(xié)議中的使用
subscript(i: Int) -> ItemType { get }
}
struct IntStack: Container {
var items = [Int]()
mutating func push(_ item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
typealias ItemType = Int // ???
mutating func append(_ item: Int) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Int {
return items[i]
}
}
struct StackAgain<Element>: Container {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
mutating func append(_ item: Element) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Element {
return items[i]
}
}
// 擴展現(xiàn)有類型來指定關(guān)聯(lián)類型
extension Array: Container {}
// now we can use an Array as a Container type.
// # 泛型where分句
// where語句,冒號+協(xié)議語句都是對泛型類型的限制
func allItemsMatch<C1: Container, C2: Container>(_ someContainer: C1, _ anotherContainer: C2) -> Bool where C1.ItemType == C2.ItemType, C1.ItemType: Equatable {
// Check that both containers contain the same number of items.
if someContainer.count != anotherContainer.count {
return false
}
// Check each pair of items to see if they are equivalent.
for i in 0..<someContainer.count {
if someContainer[i] != anotherContainer[i] {
return false
}
}
// All items match, so return true.
return true
}
var stackOfStringsAgain = StackAgain<String>()
stackOfStringsAgain.push("uno")
stackOfStringsAgain.push("dos")
stackOfStringsAgain.push("tres")
var arrayOfStrings = ["uno", "dos", "tres"]
if allItemsMatch(stackOfStringsAgain, arrayOfStrings) {
print("All items match.")
} else {
print("Not all items match.")
}
// # 帶有泛型Where分句的擴展
extension Stack where Element: Equatable {
func isTop(_ item: Element) -> Bool {
// trick: .last如果為空返回nil,否則返回包裹最后一個元素的可選項
guard let topItem = items.last else {
return false
}
return topItem == item
}
}
if stackOfStrings.isTop("tres") {
print("Top element is tres.")
} else {
print("Top element is something else.")
}
struct NotEquatable { }
var notEquatableStack = Stack<NotEquatable>()
let notEquatableValue = NotEquatable()
notEquatableStack.push(notEquatableValue)
// Error when: notEquatableStack.isTop(notEquatableValue)
extension Container where ItemType: Equatable {
func startsWith(_ item: ItemType) -> Bool {
return count >= 1 && self[0] == item
}
}
if [9, 9, 9].startsWith(42) {
print("Starts with 42.")
} else {
print("Starts with something else.")
}
extension Container where ItemType == Double {
func average() -> Double {
var sum = 0.0
for index in 0..<count {
sum += self[index]
}
return sum / Double(count)
}
}
print([1260.0, 1200.0, 98.6, 37.0].average())
// 注意: 多要求用逗號隔開
// # 關(guān)聯(lián)類型的泛型where分句
protocol NewContainer {
associatedtype Item
mutating func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
associatedtype Iterator: IteratorProtocol where Iterator.Element == Item
func makeIterator() -> Iterator
}
protocol ComparableContainer: NewContainer where Item: Comparable { }
// # 泛型下標
extension NewContainer {
subscript<Indices: Sequence>(indices: Indices) -> [Item] where Indices.Iterator.Element == Int {
var result = [Item]()
for index in indices {
result.append(self[index])
}
return result
}
}
22.泛型 Generics Swift官方文檔——版納的筆記
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來与殃,“玉大人单山,你說我怎么就攤上這事》郏” “怎么了米奸?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長爽篷。 經(jīng)常有香客問我悴晰,道長,這世上最難降的妖魔是什么逐工? 我笑而不...
- 正文 為了忘掉前任铡溪,我火速辦了婚禮,結(jié)果婚禮上钻弄,老公的妹妹穿的比我還像新娘佃却。我一直安慰自己,他們只是感情好窘俺,可當我...
- 文/花漫 我一把揭開白布饲帅。 她就那樣靜靜地躺著,像睡著了一般瘤泪。 火紅的嫁衣襯著肌膚如雪灶泵。 梳的紋絲不亂的頭發(fā)上,一...
- 文/蒼蘭香墨 我猛地睜開眼恬吕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了须床?” 一聲冷哼從身側(cè)響起铐料,我...
- 正文 年R本政府宣布渴频,位于F島的核電站芽丹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏卜朗。R本人自食惡果不足惜拔第,卻給世界環(huán)境...
- 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望场钉。 院中可真熱鬧蚊俺,春花似錦、人聲如沸逛万。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽宇植。三九已至得封,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間指郁,已是汗流浹背忙上。 一陣腳步聲響...
推薦閱讀更多精彩內(nèi)容
- 泛型的概述 我們先來了解一下泛型 泛型JDK1.5以后出現(xiàn)的機制是一種把類型明確的工作推遲到創(chuàng)建對象或者調(diào)用方法的...
- 根據(jù)《Java編程思想 (第4版)》中的描述,泛型出現(xiàn)的動機在于: 有許多原因促成了泛型的出現(xiàn)候生,而最引人注意的一個...
- 學(xué)習(xí)鏈接+知識來源 泛型類 常見的泛型類的使用:容器 Map<K 禁添,V> Container 類中保存類一對 ke...
- 什么是泛型 泛型是Java SE 1.5的新特性拆火,泛型的本質(zhì)是參數(shù)化類型歧譬,也就是說所操作的數(shù)據(jù)類型被指定為一個參數(shù)...
- ArrayList//非泛型集合 非泛型集合添加元素演示 public void Test1(){ ArrayLi...