在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
https://blog.csdn.net/weixin_34054931/article/details/88027728
swift 可以定义模板函数,如: func testFunc<T>(datas: [T]) -> T{
//处理
}
复制代码
这里有个T,使用指代类型的,这个方法定义出来,可以用来处理任意的数组:
let names = [String]()
testFunc(names)
let names2 = [Int]()
testFunc(names)
复制代码
传入 问题1:我想要这个T是具有某个特定方法的举个常用的例子: 比如写一个用来找最小值的方法, 比如可以写成: func min<T>(datas: [T]) -> T?{ if datas.count == 0 {
return nil
} var min: T = datas.first! for data in datas { if data.compareTo(min) < 0{ min = data } } return min } 里面用了compareTo方法。我要怎么确定这个T一定是有这个方法的呢? 祭出法宝:protocol
定义一个协议: protocol Comparable : NSObjectProtocol{ /**
和其他对象比较
- parameter other: 其他对象 - returns: 0 相等 -1 小于 1 大于 */ func compareTo(other: Self) -> Int } 复制代码
然后把方法定义修改为: func min<T:Comparable>(datas: [T]) -> T? 复制代码
T后面限定了类型,指定了这个T是遵循类Comparable这个协议的,那么也就具有了compareTo这个方法。在我理解里,协议的核心就在这:表明某个类具有特定的方法/能力 问题2:多个协议怎么办?假如我想处理的T类型是需要具有两个不同的能力,举个现实的例子:一个榨汁机,它接收的东西应该同时具有可被碾碎和出水两个特性,这两个特性是分开的,因为饼干不出水和椰子碾不碎。对应到代码,可悲碾碎是一个protocol里的一个方法,会出水是另一个protocol的方法。 多个协议只需要写成: func min<T:protocol<testProtocol1,testProtocol2>>(datas: [T]) -> T? 复制代码
把两个协议用protocol关键字装起来就好了。 问题3:如果我还想这个T是某个特定的类呢?比如我想T是class1这个类的对象,同时遵循testProtocol1和testProtocol2,怎么写? 祭出法宝:where关键字 方法写成: func findMinTemplateFunc<T : testCalss where T :protocol<testProtocol1,testProtocol2>>(datas: [T]) -> T?
复制代码
把协议的限定方法where里面去,where还有其他用法,我也没太用过,就不说了。 这个需求看起来好像很难发生,但只需要想一个东西就有了:抽象类。swift/OC里没强掉这个概念,但是这个东西是存在的,比如CoreData里面的NSManageredObject,你会直接使用这个类来构造对象吗?肯定不会,肯定要建自己的数据实体,也就是NSManageredObject的子类来操作了。 当有了抽象类做父类的时候,你处理的都是子类,如果你写一个针对子类的模板方法,有些子类实现了testProtocol1,有些实现了testProtocol2,有些没有。这时,就必须类、协议同时限定才能达到效果。 最后贴段例子:加入找出数组里最小值,每个值根据value1 \ value2 和rate做一段算法后的值来比较: protocol testProtocol1: NSObjectProtocol { func value1() -> Int;
}
protocol testProtocol2: NSObjectProtocol { func value2() -> Int; } //类似虚类的东西,比如NSManagedObject这种类,是不可能直接使用它来构建对象的,肯定是要配合自己建的CoreData实体 class testCalss: NSObject { var rate: Int? = 1 } func findMinTemplateFunc<T : testCalss where T :protocol<testProtocol1,testProtocol2>>(datas: [T]) -> T?{ if datas.count == 0 { return nil } var min : T = datas.first! var minRealValue = min.value1() * 10 + min.value2() * 100 if let rate = min.rate { minRealValue *= minRealValue * rate } for data in datas { var realValue = data.value1() * 10 + data.value2() * 100 if let rate = data.rate { realValue *= realValue * rate } if realValue < minRealValue { min = data minRealValue = realValue } } return min } //例子 class subClass1: testCalss, testProtocol1, testProtocol2 { func value1() -> Int { return Int(arc4random() % 10) } func value2() -> Int { return Int(arc4random() % 20) } } class subClass2: testCalss, testProtocol1, testProtocol2 { func value1() -> Int { return Int(arc4random() % 100) } func value2() -> Int { return Int(arc4random() % 200) } } func runTest(){ var array1 = [subClass1]() for _ in 0...99 { array1.append(subClass1()) } findMinTemplateFunc(array1) var array2 = [subClass2]() for _ in 0...99 { array2.append(subClass2()) } findMinTemplateFunc(array1) } runTest()
|
请发表评论