引言
在搭建项目框架时,我们通常会写很多通用代码。通用代码就必须要求灵活性和扩展性了。比如有两个非常相似的模块,只是一个是处理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
网友评论