苹果新的编程语言 Swift 语言进阶(十六)--泛型

? ? ? ? ??? ?泛型同意你定义一个宽松、可重用的函数或者类型。使用泛型能够避免代码的反复。也能以更清楚和抽象的方式来表达程序的意图。

? ? ? ? ? ?泛型是Swift语言提供的强大功能之中的一个,Swift提供的很多标准库都使用了泛型来创建,如Swift提供的数组和词典类型。

通过使用泛型,你能使用一个数组和词典来包括和存储不论什么类型的元素。

?? ? 1.1 泛型函数

?? ? ? ? ? 使用Swift语言你能定义一个能够工作于随意类型的泛型函数。从而不必为每种类型都定义一个具有同样功能的函数,这样就能够大大降低代码的反复。

? ? ? ? ? ?如对一个实现随意类型值交换(swap)的函数,能够在Swift语言中定义一个以下的泛型函数。

func?swap<T>(inout?a:T,inout?b:T)
{

? ?let?temporaryA
=a

? ?a =b

? ?b =temporaryA

}

? ? ?以上语法定义了一个实现随意类型值交换的通用版本号函数,也称为泛型函数。

定义泛型函数的语法为:定义一个通用函数名字及其后面跟着的一个闭合的三角括号<>,三角括号里包括一个字母T(能够是随意有效的标识),称为类型參数,用来指代该泛型函数定义中要使用到的类型的占位(如作为泛型函数中的输入參数和返回类型的占位)。泛型函数使用该类型參数来取代实际的类型名(能够是Int,String,
或Double等)。

? ? 类型參数使用的实际类型在每次泛型函数调用时由Swift语言依据传送给泛型函数的值的类型推定确定。例如以下样例所看到的。T被相应判断为Int和String类型。

var someInt =3

var?anotherInt =107

swap(&someInt, &anotherInt)

var?someString ="hello"

var?anotherString ="world"

swapTwoValues(&someString, &anotherString)?
?

? ? ? ? ? ?类型參数用来定义泛泛型函数中參数的类型和返回类型,以及作为泛型函数体内的类型凝视。

? ? ? ? ? ? 一个泛型函数中能够提供多个类型參数,每一个类型參数在三角括号里以逗号切割。

? 1.2 ? ? 泛型类型

? ? ? ? ? ? 与Array和Dictionary实现机制相似, Swift也同意用户定义一个能工作于随意类型的泛型类型(泛型类、泛型结构、泛型枚举)。
?

? ? ? ? ? ? 例如以下定义了一个能够使用随意类型的一个堆栈类。

?structStack<T>
{

? ?var?items
=T[]()

? ?mutating?fund?push(item:T)
{

? ? ? ?items.append(item)

? ? }

? ?mutating?func?pop()
->T {

? ? ? ?return?items.removeLast()

? ? }

?}

? ? ? ? ? ? ?与泛型函数相似,也在跟着定义的泛型类型名字后面的三角括号内定义泛型类型用到的占位类型參数。

? ? ? ? ? ? ?如上例所看到的,占位类型參数在泛型类型定义中能够用作泛型类型中的属性类型的占位。也可作为泛型类型中方法、下标方法用到的參数或返回类型的占位。

?

? ? ? ? ? ? ?占位类型參数的实际类型在泛型类型使用时使用初始化语法指定,例如以下使用上面定义泛型类型定义了一个实际类型(字符串类型)的堆栈,泛型类型的类型參数的实际类型(String)在类型名Stack后面的三角括号里指定。

? ? ? ? ? ??var stackOfStrings = Stack<String>()

? ? ? stackOfStrings.push(“uno")

? ? ? ?let?fromTheTop
=stackOfStrings.pop()

? ? 1.3 类型限制

? ? ? ? 在泛型函数和泛型类型定义中,有时须要对使用到的类型施加一些进一步的类型限制。

? ?如在Swift语言的词典类型中要求词典的键值必须保持唯一。因此Swift语言对词典的键值类型施加的类型限制是键值类型必须符合 Hashable协议(Hashable协议是Swift标准库中定义的一种特定协议,全部的Swift基本类型默认都是符合Hashable协议的,因此都是可hashable的)。

? ? ? ? 类型限制语法:

? ? ? ? 与函数參数列表的类型定义相似:在类型參数名后面放一个类或协议来规定类型參数要遵从的类型限制。两者之间以分号切割。

? ? ? ? 例如以下是一个带类型限制的泛型函数的语法:

? ? ? ??func?someFunction<T:SomeClass,U:SomeProtocol>(someT:T,someU:U)
{

? ? ? ?// function body goes here

? ? ? ?}

? ? ? 该泛型函数带有两个类型參数。分别以T和U代表,T的类型限制是T必须是SomeClass类型,U的类型限制是U必须符合SomeProtocol协议。

? ? ??泛型类型的类型限制语法与泛型函数相似。

? ? ? 例如以下是一个使用类型限制定义的在一个数组中查找值的一个泛型函数findIndex的样例及其使用。

? ? ? 该样例对类型參数施加了一个类型限制:规定类型參数必须符合Equatable协议(也是Swift标准库中定义的一种协议。要求随意符合该协议的类型必须实现==和!=操作符,用来对那种类型的两个值进行比較。全部Swift的标准类型都提供对该协议的支持)。

func?findIndex<T:Equatable>(array:T[],valueToFind:T)
->Int?

{

? ?for (index,value)?in?enumerate(array)
{

? ? ? ?if?value
==valueToFind {

? ? ? ? ? ?returnindex

? ? ? ? }

? ? }

? ?return?nil

}

let?doubleIndex =findIndex([3.14159,0.1,0.25],9.3)

? 1.4 协议的泛化

? ? ? 在定义一种协议时,作为协议定义的一部分。能够为协议用到的类型声明一个或多个相关占位类型,相关占位类型是协议用到的类型的占位名或别名,事实上际类型在协议採用时才规定。

相关类型在协议定义中使用typealiaskeyword规定。

例如以下是协议泛化的样例。

? ? ? 样例定义了一个名为Container的协议,Container协议中声明了一个称为ItemType的相关占位类型。用来在协议中作为协议规定的方法需求append的參数类型和脚本方法需求的返回类型的类型占位。

protocol Container {

? ?typealias?ItemType

? ?mutating?func?append(item:ItemType)

? ?var?count:Int
{get }

? ?subscript(i:Int)
->ItemType {get }

}

? ? ?以下是该协议的使用样例:

? struct?IntStack:
Container {

? ?// original IntStack implementation

? ?var?items
=Int[]()

? ?mutating?fund?push(item:Int)
{

? ? ? ?items.append(item)

? ? }

? ?mutating?func?pop()
->Int {

? ? ? ?return?items.removeLast()

? ? }

? ?// conformance to the Container protocol

? ?typealias?ItemType
=Int//该行能够去掉,让Swift自己主动进行类型判断

? ?mutating?unc?append(item:Int)
{

? ? ? ?self.push(item)

? ? }

? ?var?count:Int
{

? ?return?items.count

? ? }

? ?subscript(i:Int)
->Int {

? ? ? ?return?items[i]

? ? }

}

? ? ? ? ? ? ? ?在该样例中声明IntStack採用Container协议,因此IntStack须要实现Container协议规定的需求。IntStack在实现Container协议时。能够指定或者让Swift自己主动判断Container协议中定义的相关类型(别名)的实际类型。?
?

?? ? ? ? 1.5、 Where? 从句

?? ? ? ? ? ? ? 能够使用 Where 从句为泛型函数、泛型类型、泛型协议中的类型參数或相关类型进一步定义限制或需求。能够在泛型定义中使用 Where 从句规定一个相关类型符合一个确定的协议。或者规定类型參数与一个关联类型的类型同样。

? ? ? ? ? ? ? ?例如以下定义了一个泛型函数allItemsMatch,用来检查两个容器的实例中的相应次序项的值同样。

? ? ? ? ? ? ? ?该泛型函数使用Where 从句规定待比較的两个容器包括的项类型同样。而且符合Equatable协议。

? ? ? ? ?func allItemsMatch<C1:Container,C2:Container??where?C1.ItemType
==C2.ItemType,C1.ItemType:Equatable>

? ? ? ? (someContainer:C1,anotherContainer:C2)
->Bool {

? ? ? ?if?someContainer.count
!=anotherContainer.count
{

? ? ? ? ? ?return?false

? ? ? ? }

? ? ? ?for?i?in?0..someContainer.count
{

? ? ? ? ? ?if?someContainer[i]
!=anotherContainer[i] {

? ? ? ? ? ? ? ?return?false

? ? ? ? ? ? }

? ? ? ? }? ??

? ? ? ?// all items match, so return true

? ? ? ?returntrue?
? ? ?

}

? ? ? ? ? ? ? ? ? ? ? ? ?版权全部,请转载时清楚注明链接和出处,谢谢!

原文地址:https://www.cnblogs.com/ldxsuanfa/p/10804528.html

时间: 2024-10-09 17:48:59

苹果新的编程语言 Swift 语言进阶(十六)--泛型的相关文章

苹果新的编程语言 Swift 语言进阶(六)--函数和闭包

一 .函数 1.1. 函数的定义和调用 函数的定义以func关键字作为前缀,接着是函数名字,接着跟着一个可以带有参数,也可以不带参数的圆括号,接着用-> 指示函数的返回类型.函数执行体用一对大括号{}包围.如下定义了一个函数名为sayHello的函数,该函数包含一个名字为personName,类型为String的输入参数. func sayHello(personName:String) -> String { let greeting ="Hello, " +person

苹果新的编程语言 Swift 语言进阶(十四)--扩展

Swift语言的扩展是为一个已经存在的类.结构.枚举类型添加新功能的一种方式,包括为不能存取源代码的那些已经存在的类型添加功能.        扩展类似于Objective-C语言中的类别,与类别不同的是Swift语言的扩展没有名字.        扩展能够为已存在类型:     1)增加计算属性和计算静态属性:     2)定义新的实例方法和类型方法:     3)提... 请转移到此位置继续阅读,谢谢! 苹果新的编程语言 Swift 语言进阶(十四)--扩展 苹果新的编程语言 Swift 语

苹果新的编程语言 Swift 语言进阶(十五)--协议

协议定义了适合某个特定任务或功能需要的方法.属性和其它需求的一个蓝图.协议本身不提供这些需求的实现,它只是描述了一个任务或功能实现的蓝图.       协议与java 语言中的接口定义类似,都是描述了一个实现可以干什么,而本身却不包含任何实现.与接口不同的是swift语言定义的协议可以被一个类.结构.或者枚举采用,来提供协议规定需求的实际实现,而java 语言的接口只能被类实现.   ... 请麻烦转移到此位置阅读,谢谢! 苹果新的编程语言 Swift 语言进阶(十五)--协议 苹果新的编程语言

苹果新的编程语言 Swift 语言进阶(十六)--泛化

泛化允许你定义一个宽松.可重用的函数或者类型,使用泛化能够避免代码的重复,也能以更清楚和抽象的方式来表达程序的意图. 泛化是Swift语言提供的强大功能之一,Swift提供的许多标准库都使用了泛化来创建,如Swift提供的数组和词典类型.通过使用泛化,你能使用一个数组和词典来包含和存储任何类型的元素. 1.1 泛化函数 使用Swift语言你能定义一个可以工作于任意类型的泛化函数,从而不必为每种类型都定义一个具有相同功能的函数,这样就可以大大减少代码的重复. 如对一个实现任意类型值交换(swap)

苹果新的编程语言 Swift 语言进阶(十二)--选项链

选项链是使用选项来查询和调用其属性.方法或下标的一个过程,如果选项包含一个值,则属性.方法.下标的查询和调用成功,否则,调用返回nil. 选项链能用在任何类型的选项来检查对其一个属性.方法.下标的查询和调用是否成功. 选项链可以作为强制展开的替代方式使用,但选项链的使用更加安全,不会触发一个运行时错误. 在调用一个选项的属性.方法或下标方法时,通过在该选项值的后面放置一个(?)标记来规定一个选项链.这与在选项值后放置一个(!) 来强制展开选项的值非常相似.主要的不同是在选项值为nil时选项链能够

苹果新的编程语言 Swift 语言进阶(八)--属性

请转移到此位置阅读,谢谢! 苹果新的编程语言 Swift 语言进阶(八)--属性 http://blog.csdn.net/goohong/article/details/32096289 苹果新的编程语言 Swift 语言进阶(八)--属性,布布扣,bubuko.com

苹果新的编程语言 Swift 语言进阶(十一)--实例的初始化与类的析构

一 .实例的初始化          实例的初始化是准备一个类.结构或枚举的实例以便使用的过程.初始化包括设置一个实例的每一个存储属性为一个初始值,以及执行任何其它新的实例能够使用之前需要的设置或初始化. 一个类.结构或枚举能定义一个初始化方法来设置它的特性,用来确保它的实例的所有属性都有有效的初始值. 通过调用类.结构或枚举提供的初始化方法来执行实例的初始化过程. 类的实例也能实现一个析构,用来在类的实例释放之前执行任何特定的清除过程来释放分配的专有资源. 1 . 初始化方法的定义 初始化方法

苹果新的编程语言 Swift 语言进阶(七)--枚举、结构、类

一. 枚举 枚举定义了一种包含一组相关值的公共类型.枚举是Swift中的一种与类类似的类型,具有许多传统类才有的特征,例如计算属性.实例方法,能够通过扩展或协议增强功能等. 1.1 枚举定义 Swift 语言的枚举类型的定义语法如下: enum CompassPoint { case North case South case East case West } 枚举语法以一个关键字enum来标识,enum后面包含一个枚举类型名字,枚举定义全部放到一对大括号中. 在枚举中定义的值称为枚举成员值,用

苹果新的编程语言 Swift 语言进阶(三)--基本运算和扩展运算

一 基本操作运算 1. 赋值操作 在Swift 中,可以使用赋值操作为一个常量或一个变量赋值,也可以使用多元组一次为多个常量或变量赋值. Swift 的赋值操作与其它语言最大的不同是赋值操作除了能够为变量或常量赋值外本身不能够返回值. 这个特征可以避免某些条件下赋值操作错误地用于相等比较操作. 如在C语言中,if (x = =y) 很容易误写作if (x = y) ,虽然逻辑结果不正确,但C语言的编译器却无法检查出这种情况,而Swift 语言却可以有效避免这种情况发生,因为 在Swift 中if

苹果新的编程语言 Swift 语言进阶(一)--综述

Swift 是苹果开发和提供的供开发IOS 和OS X应用的一门新的语言.Swift语言基于C 和Objective-C语言,除了提供C 和Objective-C语言具有的所有语法功能外,为了编程方便和高效,Swift在语法上作了大量的优化和改进. Swift采用安全编程模式,具有许多先进的强大的功能 ,如动态运行时.编译动态进行类型检查.Closures.下标功能.自动引用计数.选项类型.通用类型和类型编译时推断.类型的扩展和嵌套.协议类型.功能和类型的通用化.操作符的定制和添加. Swift