Swift 泛型(十九)

Swift 泛型(十九),第1张

概述泛型 泛型代码可根据自定义需求,写出适用于任何类型、灵活且可重用的函数和类型,避免重复的代码,用一种清晰和抽象的思维表达代码的意思 1.泛型用途 [objc]  view plain  copy   // 普通的函数,用来交换两个值   func swapTwoInts(inout a: Int, inout b: Int) {       let temporaryA = a       a =

泛型

泛型代码可根据自定义需求,写出适用于任何类型、灵活且可重用的函数和类型,避免重复的代码,用一种清晰和抽象的思维表达代码的意思

1.泛型用途 [objc] view plain copy //普通的函数,用来交换两个值 funcswapTwoInts(inouta:Int,inoutb:Int){ lettemporaryA=a a=b b=temporaryA } varsomeInt=3 varanotherInt=107 swapTwoInts(&someInt,&anotherInt) println("someIntisNow\(someInt),andanotherIntisNow\(anotherInt)") //prints"someIntisNow107,andanotherIntisNow3" funcswapTwoStrings(inouta:String,0); background-color:inherit">b:String){ funcswapTwodoubles(inouta:Double,0); background-color:inherit">b:Double){ } 以上都是转换两个数的值,但他们代码都是一样的,只不过传入类型不一样,同一份代码就要写了三次,使用泛型就可以忽略传入值的类型,只使用一份代码

2.泛型函数 占位符T是一种类型参数的示例,类型参数指定命名为一个占位类型,并且紧随在函数名后面,使用一对尖括号括起来,一旦类型参数被确定,就可以用来定义函数的参数类型(a,b),或作为函数的返回类型,或作为函数主题的注释类型,此时类型参数所代表的占位符不管函数任何时候被调用,都会被实际类型所替代
copy funcswapTwoValues<T>(inouta:T,0); background-color:inherit">b:T){ lettemporaryA=a a=b b=temporaryA }
泛型版本的函数使用占位符(T)来替代实际类型名,占位符并没有提示T必须是什么类型,但a和b必须是用一种类型,在swapTwoValues被调用时才能确定T所表示的类型
copy
funcswapTwoInts(inoutb:Int) funcswapTwoValues<T>(inoutb:T) swapTwoValues(&someInt,0); background-color:inherit">//someIntisnow107,andanotherIntisnow3 varsomeString="hello" varanotherString="world" swapTwoValues(&someString,&anotherString) //someStringisnow"world",andanotherStringisnow"hello"
3.泛型类型 Swift允许自定义泛型类型,这些自定义类、结构体和枚举作用于任何类型
copy //以下是一个用泛型写的栈Stack,模拟栈的push和pop structIntStack{ varitems=Int[]() mutatingfuncpush(item:Int){ items.append(item) mutatingfuncpop()->Int{ returnitems.removeLast() } //Stack提供两个方法,push和pop,从栈中压进一个值和d出一个值,但只能用于int值,下面定义一个泛型Stack类,可处理任何类型的栈 structStack<T>{ varitems=T[]() mutatingfuncpush(item:T){ items.append(item) mutatingfuncpop()->T{ returnitems.removeLast() varstackOfStrings=Stack<String>() stackOfStrings.push("uno") stackOfStrings.push("dos") stackOfStrings.push("tres") stackOfStrings.push("cuatro") //thestacknowcontains4strings letfromTheTop=stackOfStrings.pop() //fromTheTopisequalto"cuatro",andthestacknowcontains3strings
4.类型约束 有时候对使用在泛型函数和泛型类型上的类型强制约束为某种特定的类型是非常有用的,可以指定一个必须继承自指定类的类型参数,或者遵循一个特定的协议或协议构成
4.1语法 copy //假定函数有两个类型参数,类型参数T必须是SomeClass子类的类型约束,类型参数U必须遵循SomeProtocol协议的类型约束 funcsomeFunction<T:SomeClass,U:SomeProtocol>(someT:T,someU:U){ //functionbodygoeshere }
4.2实例 非泛型函数,查找以给定的String数组,若找到匹配的字符串,返回下标
copy funcfindStringIndex(array:String[],0); background-color:inherit">valueToFind:String)->Int?{ for(index,value)inenumerate(array){ ifvalue==valueToFind{ returnindex returnnil letstrings=["cat","dog","llama","parakeet","terrapin"] ifletfoundIndex=findStringIndex(strings,"llama"){ println("Theindexofllamais\(foundIndex)") //prints"Theindexofllamais2" //使用泛型实现相同功能,但是下面这个泛型函数不会被编译,在等式value==valueToFind里,不是所有的类型都可以用等式==来进行比较,如果是自己创建的自定义类型,Swfit就无法猜到这个等于的意思,所以编译下面代码的时候就会报错 funcfindIndex<T>(array:T[],0); background-color:inherit">valueToFind:T)->Int?{ }
Swift标准库定义了一个Equatable协议,要求任何遵循的类型实现等式 == 和不等式 != 对两个该类型进行比较。所有的Swift标准类型自动支持Equatable协议
copy funcfindIndex<T:Equatable>(array:T[],248)"> letdoubleIndex=findIndex([3.14159,0.1,0.25],9.3) //doubleIndexisanoptionalIntwithnovalue,because9.3isnotinthearray letstringIndex=findIndex(["Mike","Malcolm","Andrea"],"Andrea") //stringIndexisanoptionalIntcontainingavalueof2
5.关联类型 定义一个协议的时候,声明一个或多个关联类型作为协议定义的一部分是非常有用的,一个关联类型给定作用于协议部分的类型一个节点名。作用于关联类型上实际是不需要指定的,直到该协议接受。关联类型为 typealias关键字
5.1实例 定义ItemType关联类型,1. append方法添加一个新的item 2. count方法获取数量 3. 通过索引值检索到每一个item
copy protocolContainer{ typealiasItemType mutatingfuncappend(item:ItemType) varcount:Int{get} subscript(i:Int)->ItemType{get} //IntStack的非泛型版本,实现Container协议的所有三个要求 structIntStack:Container{ //originalIntStackimplementation //conformancetotheContainerprotocol typealiasItemType=Int mutatingfuncappend(item:Int){ self.push(item) varcount:Int{ returnitems.count subscript(i:Int)->Int{ returnitems[i] //遵循Container协议的泛型版本 structStack<T>:Container{ //originalStack<T>implementation //conformancetotheContainerprotocol mutatingfuncappend(item:T){ subscript(i:Int)->T{ }
5.2扩展一个存在的类型为已指定关联类型 Swift中的Array已经提供了一个append方法,一个count属性和通过下标查找元素的功能,都已满足Container协议的要求,就意味着可以扩展Array去遵循Container协议,只要通过简单声明Array适用于该协议就可以了
copy extensionArray:Container{}
6.Where语句
where语句要求一个关联类型遵循一个特定的协议,或那个特定的类型参数和关联类型可以是相同的
copy //定义allitemsMatch的泛型函数检查两个Container单例是否包含相同顺序的相同元素,如果匹配返回ture,否则返回false funcallitemsMatch< C1:Container,0); background-color:inherit">C2:Container whereC1.ItemType==C2.ItemType,C1.ItemType:Equatable> (someContainer:C1,0); background-color:inherit">anotherContainer:C2)->Bool{ //checkthatbothcontainerscontainthesamenumberofitems ifsomeContainer.count!=anotherContainer.count{ returnfalse //checkeachpairofitemstoseeiftheyareequivalent foriin0..someContainer.count{ ifsomeContainer[i]!=anotherContainer[i]{ //allitemsmatch,soreturntrue true varstackOfStrings=Stack<String>() stackOfStrings.push("uno") stackOfStrings.push("dos") stackOfStrings.push("tres") vararrayofstrings=["uno","dos","tres"] ifallitemsMatch(stackOfStrings,arrayofstrings){ println("Allitemsmatch.") }else{ println("Notallitemsmatch.") //prints"Allitemsmatch."

FROM: http://blog.csdn.net/huangchentao/article/details/32718325

总结

以上是内存溢出为你收集整理的Swift 泛型(十九)全部内容,希望文章能够帮你解决Swift 泛型(十九)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1076724.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存