第二十九章 Swift 泛型

2019-06-07  本文已影响0人  我有小尾巴快看

Swift 提供了泛型让你写出灵活且可重用的函数和类型。

1. 集合类

在Swift的集合类中,元素类型是必须指定的,如果元素类型不同,则需要指定为AnyAnyObject

class Peron {
    
}

class User {
    
}

var arr = [Peron]()
arr.append(Peron())
arr.append(User()) // error: Cannot convert value of type 'User' to expected argument type 'Peron'

如果你试图违反指定的泛型进行操作,编译器会报错。

2. 指定参数类型

当我们有一个函数、算法可以运用给多种类型时,在OC中只能指派给父类或id类型,填参时没关系,但是相关返回值则不是我们所期望的。

Swift泛型则可以完美解决这种问题。

struct Number<T> {
    var value: T
    
    init(value: T) {
        self.value = value
    }
}

let num1 = Number.init(value: 5)   // num1.value: Int = 5
let num2 = Number.init(value: 5.5) // num2.value: Double = 5.5

3. 对泛型进行约束

很多时候,我们只会有其中有限的场景进行我们的修改,不想影响到其他的场景,那么我们可以给泛型进行约束。

struct Number<T: Numeric> {
    var value: T
    
    init(value: T) {
        self.value = value
    }
}

let num1 = Number.init(value: 5)   // num1.value: Int = 5
let num2 = Number.init(value: 5.5) // num2.value: Double = 5.5
let num3 = Number.init(value: "Apple") // error: Argument type 'String' does not conform to expected type 'Numeric'

上例约束了泛型T必须实现Numeric协议,故传入的String类型会报错,而IntDouble则没有受到影响。

我们也可以在扩展中对泛型进行约束,这里对Int类型的T进行了扩展,添加了一个log函数,Double类型的T调用会报错。

extension Number where T == Int {
    func log() {
        print("Int value: \(self.value)")
    }
}

num1.log() // Int value: 5
num2.log() // 'Number<Double>' is not convertible to 'Number<Int>'
上一篇 下一篇

猜你喜欢

热点阅读