- 泛型視圖解決存儲不一樣的數據類型,或者方法的入參是不一樣的數據類型。這樣能夠優雅的減小了不少沒必要要的重複代碼。
func exchangeTwoValue<T>(a:inout T, b: inout T){
let temp = a
a = b
b = temp
}
var a = 3
var b = 4
exchangeTwoValue(a: &a, b: &b)
print(String(a) + " " + String(b))
var c = "abc"
var d = "123"
exchangeTwoValue(a: &c, b: &d)
print(String(c) + " " + String(d))
//系統庫函數解決交互兩個值
swap(&c, &d)
print(String(c) + " " + String(d))
複製代碼
- 利用泛型實現一個自定義棧
//1. 利用泛型實現自定義棧
struct Stack<Element> {
var items = [Element]()
mutating func push(_ a: Element){
items.append(a)
}
mutating func pop(){
items.removeLast()
}
}
var aStack = Stack<Any>()
aStack.push(1)
aStack.push(2.0)
aStack.push("1")
print(aStack.items)
aStack.pop()
print(aStack.items)
複製代碼
- 對泛型類型擴展
//2. 利用擴展返回棧頂
extension Stack {
var topStack: Element? {
return items.isEmpty ? nil : items.last
}
}
print(aStack.topStack as Any)
複製代碼
- 類型約束
func findIndex<T: Equatable>(findValue: T, array: [T]) -> Int?{
for (index, value) in array.enumerated(){
if value == findValue {
return index
}
}
return nil
}
var a = [1,2,3,4,5]
print(findIndex(findValue: 3, array: a) as Any)
複製代碼
- 關聯類型
protocol Container {
associatedtype Item
mutating func append(item: Item)
var count: Int{get}
subscript(index: Int) -> Item { get }
}
struct Stack<Element>: Container {
var items = [Element]()
mutating func push(_ a: Element){
items.append(a)
}
mutating func pop(){
items.removeLast()
}
mutating func append(item: Element) {
push(item)
}
var count: Int{
return items.count
}
subscript(index: Int) -> Element {
return items[index]
}
}
var aStack = Stack<Any>()
aStack.push(1)
aStack.push(2.0)
aStack.push("1")
print(aStack.items)
print(aStack[2])
複製代碼
- 協議裏的關聯類型能夠添加條件
protocol Container {
associatedtype Item: Equatable
mutating func append(item: Item)
var count: Int{get}
subscript(index: Int) -> Item { get }
}
複製代碼
- 泛型Where語句
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int {get}
subscript(item: Int) -> Item{get}
}
struct Stack<Element>: Container {
var items = [Element]()
mutating func append(_ item: Element) {
items.append(item)
}
var count: Int {
return items.count
}
subscript(item: Int) -> Item {
return items[item]
}
}
extension Array: Container {}
func allItemsMatch<T: Container, U: Container> (a: T, b: U) -> Bool
where T.Item == U.Item, T.Item: Equatable {
if a.count != b.count {
return false
}
for index in 0..<a.count {
if a[index] != b[index] {
return false
}
}
return true
}
var a = Stack<String>()
a.append("a")
a.append("b")
a.append("c")
a.append("d")
a.append("e")
a.append("f")
var b = [
"a",
"1",
"c",
"d",
"e",
"f"
]
print(allItemsMatch(a: a, b: b))
複製代碼
- 擴展泛型協議使用where語句
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int {get}
subscript(item: Int) -> Item{get}
}
struct Stack<Element>: Container {
var items = [Element]()
mutating func append(_ item: Element) {
items.append(item)
}
var count: Int {
return items.count
}
subscript(item: Int) -> Item {
return items[item]
}
}
extension Array: Container {}
func allItemsMatch<T: Container, U: Container> (a: T, b: U) -> Bool
where T.Item == U.Item, T.Item: Equatable {
if a.count != b.count {
return false
}
for index in 0..<a.count {
if a[index] != b[index] {
return false
}
}
return true
}
extension Stack where Element: Equatable {
//1. 擴展判斷是不是棧頂
func isTopStack(item: Element) -> Bool {
guard let topItem = items.last else {
return false
}
return topItem == item
}
//2. 擴展判斷棧低
func isBottomStack(item: Element) -> Bool {
return count >= 1 && items[0] == item
}
}
var aStack = Stack<String>()
aStack.append("a")
aStack.append("b")
aStack.append("c")
print(aStack.isTopStack(item: "c"))
print(aStack.isBottomStack(item: "b"))
//擴展Container協議,新增若是每一個元素都是小數類型,那麼能夠計算平均值
extension Container where Item == Double {
func avg() -> Double {
var sum = 0.0
for item in 0..<count{
sum += self[item]
}
return sum/Double(count)
}
}
var b = [
1.0,
2.0,
3.0,
4.0
]
print(b.avg())
複製代碼
- 泛型下標
// 1. 封裝數據結構
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int{get}
subscript(index: Int) -> Item{get}
}
extension Array: Container {}
struct Stack<Element>: Container {
var items = [Element]()
mutating func append(_ item: Element) {
items.append(item)
}
var count: Int {
return items.count
}
subscript(index: Int) -> Element {
return items[index]
}
}
// 2. 給兩種數據結構擴展一個方法
extension Container {
subscript<T: Sequence>(set: T) -> [Item]
where T.Iterator.Element == Int {
var items = [Item]()
for item in set{
items.append(self[item])
}
return items
}
}
var aStack = Stack<String>()
aStack.append("a")
aStack.append("b")
aStack.append("c")
aStack.append("d")
print(aStack[[0,2,3]])
//打印以下
//["a", "c", "d"]
複製代碼
- 總結
- 泛型視圖解決存儲多種數據類型,和方法的入參是多種數據類型。
- 一個方法入參不用泛型切其實能夠用Any來解決。
- 利用Any來代替泛型很差,咱們應該在方法入參用泛型。
- 泛型能夠作到入參和返回值得統一性。可是Any作很少。
- 泛型能夠在調用時候指定特定的數據類型。可是Any也作不到。 泛型