1.方法的泛型
//泛型约束(冒号后边跟class或者协议,传入的参数someT和someU必须是遵循该协议或类---(NAArray类,Comparable协议))
func someFunction<T:NSArray, U:Comparable>(someT: T, someU: U) {
// 这里是泛型函数的函数体部分
}
func comparTwo<T:Comparable>( _ a:T,_ b:T) -> Bool {
return a>b
}
与OC中的id有点类似,只是可以遵循协议或者指定类型
2.struct的泛型
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
}
var stackOfStrings = Stack<String>()
print("字符串元素入栈: ")
stackOfStrings.push("google")
stackOfStrings.push("runoob")
print(stackOfStrings.items);
let deletetos = stackOfStrings.pop()
print("出栈元素: " + deletetos)
var stackOfInts = Stack<Int>()
print("整数元素入栈: ")
stackOfInts.push(1)
stackOfInts.push(2)
print(stackOfInts.items);
(1)struct也可以使用泛型,当调用结构体的时候可以指定泛型的具体类型
//协议
protocol Container {
//associatedtype 关键字来指定关联类型(就是定义一个泛型名字叫ItemType,这个等价于下边的Element,都是一个泛型)
associatedtype ItemType
//添加一个新元素到容器里
mutating func append(item:ItemType)
//获取容器中元素的数
var count: Int{get}
//通过索引值类型为 Int 的下标检索到容器中的每一个元素
//下标脚本是系统提供的可以对struct或者enum或者数组等重写的一个属性
subscript(i:Int) -> ItemType {get}
//不一定是一维的,也可以是二维的
// subscript(row: Int, col: Int) -> Double {
// get
// }
}
//Stack 遵循Container协议, (Element可以设置遵循某个协议)(这个协议可以写在extension中的where里)
struct Stack<Element>:Container {
var items = [Element]()
mutating func push(item:Element){
items.append(item)
}
mutating func pop(item:Element){
items.removeLast()
}
//协议部分
mutating func append(item: Element) {
self.push(item: item)
}
var count: Int{
return items.count
}
subscript(i: Int) ->Element{
return items[i]
}
}
//where是对Stack传入的元素的类型约束,必须遵循可以进行等于比较的协议(传入数组就不行),其实也可以在Stack定义的时候让元素遵循某个协议,这个协议的范围只是在调用这个扩展方法里,上边的push元素不遵循
extension Stack where Element:Equatable{
func isTop(item:Element) -> Bool {
guard let topItem = items.last else {
return false
}
return topItem == item
}
}
(2)调用Stack
func one(){
var bbb = Stack<String>()
bbb.push(item:"google")
bbb.push(item:"runoob")
bbb.push(item:"taobao")
let mm = bbb.isTop(item: "optional")
print("istop==\(mm)")
//元素列表
print(bbb.items)
print(bbb.count)
var aaa = Stack<String>()
aaa.push(item:"google")
aaa.push(item:"runoob")
aaa.push(item:"taobao")
}
(3)写一个泛型遵循Container协议的方法,正好上述Stack遵循Container协议,可以把aaa和bbb作为参数传进去
func allItemsMatch<C1:Container,C2:Container>(containter1:C1,containter2:C2) -> Bool
where C1.ItemType == C2.ItemType, C1.ItemType:Equatable
{
if containter1.count != containter2.count {
return false
}
for i in 0..<containter1.count {
if containter1[i] != containter2[i]{
return false
}
}
return true
}
调用方法
if allItemsMatch(containter1: aaa, containter2: bbb) {
print("aaa == bbb")
}else{
print("aaa != bbb")
}
补充:
subscript是系统提供的,通常情况下,我们在使用数组(Array)或字典(Dictionary)时会使用到下标。其实在Swift中,我们还可以给类、结构、枚举等自定义下标(subscript)。
subscript例子:https://blog.csdn.net/sinat_27706697/article/details/47122137
整合的代码加自己的理解,参考文章:http://www.runoob.com/swift/swift-generics.html