Swift每日学习-泛型

Swift泛型的简单介绍

泛型在类,结构体,函数和枚举中经常会使用,他的引入可以起到占位符的作用,类型暂时不确定只有在函数调用的时候才知道类型,这个时候我们都可以使用泛型。

例如,Array和Dictionry都是泛型集,我们可以创建一个String类型的Array也可以创建一个Int类型的Array,同样在创建Dictionary的时候我们也可以存储各种类型的数据

下面我们举个实际场景的例子,我们接到一个需求将一个Int数组添加到数组后面。

// 定义一个函数,要求追加数组数据到指定一个数组中
// tip:inout 修饰 可以修改函数外的值,我们这边需要给该数组添加数据所以适应inout修饰
func appendIntToArray(src:[Int], dest:inout [Int]) {
    // 遍历并加到数组后边
    for element in src {
        dest.append(element)
    }
}

// 使用appendIntToArray添加整形数组数据
var arr = [22,15]
appendIntToArray(src: [2,3], dest: &arr)
print(arr)  // [22, 15, 2, 3]
复制代码

这时候你刚完成了这个需求,你们产品过来说不行这块要改,我们也要可以追加字符串

// 那么再要求让你实现添加字符串呢,好吧重写一个
func appendStringToArray(src:[String], dest:inout [String]) {
    for element in src {
        dest.append(element)
    }
}

var strArr = ["OC","Swift"]
appendStringToArray(src: ["C", "C++"], dest: &strArr)
print(strArr) /// ["OC", "Swift", "C", "C++"]
复制代码

如果这个时候产品又提出我们要添加其他类型数据,这时候我们发现只要新增一个类型我们就要多一个方法来实现,这样既不容易维护代码可读性不高,我们和这个时候就要使用泛型来解决的这问题

// 这样一个方法可以适配多种场景
var arr2 = [15,28]
appendArray(src: [39,58], dest: &arr2)  
print(arr2)                       // [15, 28, 39, 58]

var strArr2 = ["OC","Swift"]
appendArray(src: ["OC","Swift"], dest: &strArr2)
print(strArr2)                    // ["OC", "Swift", "OC", "Swift"]

var doubleArr = [1.4,2.4]
appendArray(src: [5.5,4.6], dest: &doubleArr)
print(doubleArr)                  // [1.4, 2.4, 5.5, 4.6]
复制代码

其实简单来理解,就像是摆了一排没有名字的板凳,张三可以来坐李四可以来坐,使用起来十分方便

泛型的简单使用

1.泛型函数,如上文所展示的。泛系函数主要的写法如下:

// 定义泛型函数
func 函数名<泛型1,泛型2,…>(形参列表)->返回值类型
{
// 函数体...
}
复制代码

举一个实际的列子交换两个字符串的值

/// 使用泛型函数交换两个参数的值
func changeValueToValue<T>(value1: inout T,value2: inout T) {
    let value3 = value1
    value1 = value2
    value2 = value3
}
var  str1 = "2222";
var  str2 = "3333";
print(str1+str2) // 22223333
changeValueToValue(value1: &str1, value2: &str2)
print(str1+str2) // 33332222
复制代码

2.泛型约束,为泛型类型添加约束*

泛型约束大致分为以下几种:

继承约束,泛型类型必须是某个类的子类类型
协议约束,泛型类型必须遵循某些协议
条件约束,泛型类型必须满足某种条件
约束的大概使用格式

// 继承约束使用格式
func 函数名<泛型: 继承父类>(参数列表) -> 返回值 {
// 函数体,泛型类型是某个类的子类类型
}
// 协议约束使用格式
func 函数名<泛型: 协议>(参数列表) -> 返回值 {
// 函数体,泛型类型遵循某些协议
}
// 条件约束使用格式
func 函数名<泛型1, 泛型2 where 条件>(参数列表) -> 返回值 {
// 函数体,泛型类型满足某些条件
}
复制代码

继承约束使用范例:

class Person {

    func des() {
        print("我是一个人")
    }
}

class Man:Person {
    override func des() {
        print("我是一个男人")
    }
}

class WoMan:Person {
    override func des() {
        print("我是一个女人")
    }
}

// 继承约束,泛型类型必须是Person类的子类类型
func PersonIs<T:Person>(person:T) {
    person.des()
}
PersonIs(person: Person()) // 我是一个人
PersonIs(person: Man()) // 我是一个男人
PersonIs(person: WoMan()) // 我是一个女人

复制代码

协议约束使用范例:

Equatable是swift标准协议库,遵循该协议,可以进行==相等式和!=不等式的对比

/// 查看改数组中是否包含该元素
/// - Parameters:
///   - array: 数组
///   - value: 目标
func findValueIsIn<T:Equatable>(array:[T],value:T) -> Bool {
    for element in array {
        if element == value { // 遵循Equatable可以进行相等式的判断
            return true
        }
    }
    return false
}
// 查找一个字符串数组
findValueIsIn(array: ["222","000","1212"], value: "1212") // true
// 查找一个double数组
findValueIsIn(array: [22.2,3.03,4.56], value: 0) // false
复制代码

条件约束使用范例:

// 定义一个泛型协议,和其他泛型使用方式不同,这里泛型是以关联类型形式使用的

protocol Stackable{
    // 声明一个关联类型,使用associatedtype关键字
    associatedtype ItemType
    mutating func add(item:ItemType)
    mutating func ret() -> ItemType
}


struct Stack<T>:Stackable{
    var store = [T]()
    mutating func add(item: T) {
        store.append(item)
    }
    mutating func ret() -> T {
        return store.removeLast()
    }
}

// 创建Stack结构体,泛型类型为String
var stackOne = Stack<String>()
stackOne.add(item: "111")
stackOne.add(item: "222")
stackOne.add(item: "333")
let t = stackOne.ret()
print("t = \(t) stackone= \(stackOne)") //结果:t = 333 stackone= Stack<String>(store: ["111", "222"])

/// 写一个泛型条件约束的方法
func addItemOneToTwo<T1:Stackable, T2:Stackable> (stackOne: inout T1,stackTwo: inout T2)
where T1.ItemType == T2.ItemType {
    let stckoneItem = stackOne.ret()
    stackTwo.add(item: stckoneItem)
}

var stackTwo = Stack<String>()
addItemOneToTwo(stackOne: &stackOne, stackTwo: &stackTwo)
print("stackone= \(stackOne) stackTwo = \(stackTwo) ") //stackone= Stack<String>(store: ["111"]) stackTwo = Stack<String>(store: ["222"]) 
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享