一步步学习Swift

Swift学习泛型

2020-10-15  本文已影响0人  冷武橘
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)

swapTwoInts(::) 函数很实用,但是它只能用于 Int 值。如果你想交换两个 String 值,或者两个 Double 值,你只能再写更多的函数。

一、函数

为了解决类似上面的问题,我们可以用一个泛型函数去表示一个函数

func swapTwo<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}
var someInt = 3
var anotherInt = 107
swapTwo(&someInt, &anotherInt)

var someString = “3”
var anotherString = “17”
swap(&someString, &anotherString)

1.2、泛型函数赋给变量

func test<T1,T2>(t1:T1,t2:T2){
    print(t1,t2)
}

var fn:(Int,Int)->() = test
var fn1:(Int,String)->() = test
var fn2:(String,String)->() = test
fn(10,20)
fn1(10,"你好")
fn2("大家好","你好")

二、类型

除了泛型函数,Swift允许你定义自己的泛型类型。它们是可以用于任意类型的自定义类、结构体、枚举,和 Array 、 Dictionary 方式类似。

class Stack<Element>{
    var items = [Element]()
     func push(_ item: Element) {
         items.append(item)
     }
   func pop() -> Element {
         return items.removeLast()
     }
}
class Stack<Element>{
    var items = [Element]()
     func push(_ item: Element) {
         items.append(item)
     }
   func pop() -> Element {
         return items.removeLast()
     }
}

var stack = Stack<String>()
stack.push(“ssss”)

var stack1 = Stack<Int>()
stack1.push(10)
struct Stack<Element> {
    var items = [Element]()
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
}
stackOfStrings = Stack<String>()
stackOfStrings.push(“uno”)
stackOfStrings.push(“dos”)
stackOfStrings.push(“tres”)
stackOfStrings.push(“cuatro”)
enum Socre<T> {
   case point(T)
   case grade(String)
}

let score0 = Socre<Int>.grade("")
let score1 = Socre.point(3)
let score2 = Socre<Int>.point(100)

三、关联类型

在泛型函数中,你可以在函数名后面紧跟着一个类型形式参数,来表明泛型。然在协议中你不能这样去表示,编译器是不允许的。你需要在内部声明一个关联类型来表示泛型。

protocol Test {
    associatedtype Element
    mutating func append(_ item: Element)
       var count: Int { get }
       subscript(i: Int) -> Element { get }
}
class Student: Test {
    typealias Element = String// 给关联类型设定真实类型
    func append(_ item: String) {}
    var count: Int = 0
    subscript(i: Int) -> String {
         return “333”
    }
}
class Person: Test {
    typealias Element = Int// 给关联类型设定真实类型
    func append(_ item: Int) {}
    var count: Int = 0
    subscript(i: Int) -> Int {
         return 333
    }
}

四、类型约束

protocol Runnable{}
class Person{}
func swapValues<T:Person&Runnable>(a:T,b:T){}
protocol Stackable {
    associatedtype Eleement:Equatable
} 
class Stack<E:Equatable>:Stackable{
    typealias Eleement = E
}

var stack = Stack<Int>()

五、不透明类型

如果协议中有 associatedtype,


截屏2020-01-14下午5.12.29.png
解决方案1:使用泛型
func test<T:Runnable>(a:Int) ->  T{
    return Person() as! T
}
解决方案2:不透明类型

使用some关键字声明一个不透明类型

func test(a:Int) ->  some Runnable{
    return Person()
}
上一篇下一篇

猜你喜欢

热点阅读