美文网首页iOS学习开发
Swift的编程利器-泛型

Swift的编程利器-泛型

作者: howard0103 | 来源:发表于2019-05-09 15:32 被阅读124次

    引言

    在搭建项目框架时,我们通常会写很多通用代码。通用代码就必须要求灵活性和扩展性了。比如有两个非常相似的模块,只是一个是处理int类型,另一个处理string类型,或者是其它数据类型,当然我们可以分别写不同的方法来分别处理,也可以在一个方法里面用if-elseif来分别处理。但这样的代码太复杂,灵活性和扩展性都不高。要解决这个问题怎么办呢?
    泛型就是为了解决这个问题产生的。很多编程语言里都有泛型,在做Android项目时就使用过java语言里的泛型,当时就感觉非常友好,灵活非常高。
    今天我们来聊聊swift语言中的泛型,oc语言中本来是没有泛型的,新的xcode在swift的影响下才给oc加入了泛型并且也是伪泛型。

    swift泛型

    为什么要使用泛型

    泛型是为了编程更加的灵活,避免重复的代码,清晰和抽象的方式来表达代码的意图。
    为了解释这句话,下面举个简单的例子来说明
    场景一:写一个方法把Int变量A和Int变量B的值交换一下

    //1 定义一个方法
    func exchange(a: Int, b:Int) {
        let temp = a
        a = b
        b = temp
    }
    //2 具体使用
    var oneInt = 1
    var twoInt = 2
    exchange(a:&oneInt, b:&twoInt)
    print("oneInt= \(oneInt), twoInt= \(twoInt)") //打印: oneInt=2,twoInt=1
    

    场景二:写一个方法把String变量A和String变量B的值交换一下

    //1 定义一个方法
    func exchange(a: String, b:String) {
        let temp = a
        a = b
        b = temp
    }
    //2 具体使用
    var oneStr= "str1"
    var twoStr= "str2"
    exchange(a:&oneStr, b:&twoStr)
    print("one= \(oneStr), twoStr= \(twoStr)") //打印: oneStr=str2,twoStr=str1
    

    大家想必已经发现问题了吧,场景一和场景二非常的类似,只是处理的数据类型不一样,如果还想处理其它数据类型呢?这样实现就太复杂了。
    使用泛型便可解决这个问题。

    我们来看看利用泛型是如何实现的

    //1 定义一个泛型方法
    func exchange<T>(a: T, b:T) {
        let temp = a
        a = b
        b = temp
    }
    //2 具体使用
    var oneInt = 1
    var twoInt = 2
    exchange(a:&oneInt, b:&twoInt)
    print("oneInt= \(oneInt), twoInt= \(twoInt)") //打印: oneInt=2,twoInt=1
    
    var oneStr= "str1"
    var twoStr= "str2"
    exchange(a:&oneStr, b:&twoStr)
    print("one= \(oneStr), twoStr= \(twoStr)") //打印: oneStr=str2,twoStr=str1
    

    定义一个方法,随意使用,太棒了!

    泛型 vs Any

    泛型可以指定任意类型,这个时候大家应该会联想到Any,Any也是可以指定任意类型的,话不多说,先上一段代码,大家来看看他们的区别

    //函数一
    func method1<T>(a: T, b: T) ->T {
         ...
    }
    //函数二
    func method2(a: Any, b: Any) ->Any {
         ...
    }
    

    看到他们的区别了吧
    相同之处:
    a,b参数类型和返回值类型都可以是任意类型
    不同之处:
    函数一中a,b两参数和返回值类型必须是同一类型T
    函数二中a,b两参数和返回值类型都可以是任意类型,不一定相同
    为什么会这样呢?
    因为泛型的类型检查是由编译器负责的,而Any类型则避开了类型检查。
    这里便体现了泛型的一大优点:安全性强。
    为什么会这样说呢?因为使用泛型程序在编译的时候,就会帮我们发现问题,而使用Any,程序就只有在运行的时候发现问题了。尽量要把Bug消灭在摇篮中呀!

    AnyObject?
    大家会不会想到AnyObject,其实这个并不是任意类型,它只是用于任何类(class)的实例。比如基本数据类型,值类型就不能用AnyObject来修饰

    泛型是如何使用的呢?
    • 泛型函数
    func exchange<T>(a: T, b:T) {
         ...
    }
    
    • 泛型类型
    struct ClassA<T> {
         var arr = [T]()
         mutating func add(item: T) {
             arr.append(item) 
        }
    }
    
    • 泛型约束
    func methodXXX<T: ClassXXX>(param: T) {
         ...
    }
    
    • 泛型协议
    protocol MyProtocol {
       //声明一个关联类型,使用associatedtype关键字
       associatedtype ItemType
    }
    func methodXXX<T1: MyProtocol, T2: MyProtocol where T1.ItemType == T2.ItemType>(param1: T1, param2: T2) {
        ...
    }
    

    这里T1和T2都遵循了MyProtocol协议,并且T1和T2包含的泛型类型是一致的

    总结

    • 泛型不管在java和swift语言中都有很重要的地位,我们应该好好去挖掘里面的知识点
    • 使用泛型可以大大简化代码,尤其在写通用性强的代码时
    • 学会了泛型编程,会让你的编程水平上一个新的台阶

    如果有任何问题,或者有什么想法,随时联系我,大家一起交流,共同进步。
    我的邮箱 344185723@qq.com

    相关文章

      网友评论

        本文标题:Swift的编程利器-泛型

        本文链接:https://www.haomeiwen.com/subject/xgdwoqtx.html