苹果新的编程语言 Swift 语言进阶(十六)--泛型
泛型允许你定义一个宽松、可重用的函数或者类型,使用泛型能够避免代码的重复,也能以更清楚和抽象的方式来表达程序的意图。
泛型是Swift语言提供的强大功能之一,Swift提供的许多标准库都使用了泛型来创建,如Swift提供的数组和词典类型。通过使用泛型,你能使用一个数组和词典来包含和存储任何类型的元素。
1.1 泛型函数
使用Swift语言你能定义一个可以工作于任意类型的泛型函数,从而不必为每种类型都定义一个具有相同功能的函数,这样就可以大大减少代码的重复。
如对一个实现任意类型值交换(swap)的函数,可以在Swift语言中定义一个下面的泛型函数。
func swap<T>(inout a:T,inout b:T)
{let temporaryA
=aa =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 协议的泛化
在定义一种协议时,作为协议定义的一部分,能够为协议用到的类型声明一个或多个相关占位类型,相关占位类型是协议用到的类型的占位名或别名,其实际类型在协议采用时才规定。相关类型在协议定义中使用typealias关键字规定。如下是协议泛化的例子。
例子定义了一个名为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
}
版权所有,请转载时清楚注明链接和出处,谢谢!
苹果新的编程语言 Swift 语言进阶(十六)--泛型的更多相关文章
- 苹果新的编程语言 Swift 语言进阶(六)--函数和闭包
一 .函数 1.1. 函数的定义和调用 函数的定义以funckeyword作为前缀,接着是函数名字,接着跟着一个能够带有參数.也能够不带參数的圆括号.接着用-> 指示函数的返回类型. 函数运行体 ...
- 苹果新的编程语言 Swift 语言进阶(十五)--协议
协议定义了适合某个特定任务或功能需要的方法.属性和其它需求的一个蓝图.协议本身不提供这些需求的实现,它只是描述了一个任务或功能实现的蓝图. 协议与java 语言中的接口定义类似,都是描述了一个实现可以 ...
- 苹果新的编程语言 Swift 语言进阶(十四)--扩展
扩展是为一个已经存在的类.结构.枚举类型添加新功能的一种方式,包括为不能存取源代码的那些已经存在的类型添加功能. 扩展类似于Objective-C语言中的类别,与类别不同的是Swift语言的扩展没有名 ...
- 苹果新的编程语言 Swift 语言进阶(一)--综述
Swift 是苹果开发和提供的供开发IOS 和OS X应用的一门新的语言.Swift语言基于C 和Objective-C语言,除了提供C 和Objective-C语言具有的所有语法功能外,为了编程方便 ...
- 苹果新的编程语言 Swift 语言进阶(三)--基本运算和扩展运算
一 基本操作运算 1. 赋值操作 在Swift 中,能够使用赋值操作为一个常量或一个变量赋值,也能够使用多元组一次为多个常量或变量赋值. Swift 的赋值操作与其他语言最大的不同是赋值操作除了可以为 ...
- 苹果新的编程语言 Swift 语言进阶(七)--枚举、结构、类
Swift语言中,具有类特征的类型包括三种,即枚举类型.结构类型(包括基本类型,基本类型实际都是结构类型的特例).类.其中枚举类型.结构类型是属于值类型,类属于引用类型.三种类型都可以添加属性.方法. ...
- 苹果新的编程语言 Swift 语言进阶(四)--字符串和收集类型
一.字符串( String )和字符类型(Character) 字符串是一种字符的带次序的收集类型(相当于数组),字符是字符串中的元素. 在Swift 语言中,字符串是编码独立的Unicode字符的 ...
- 苹果新的编程语言 Swift 语言进阶(二)--基本数据类型
一 . 常量和变量 Swift语言 对常量和变量的声明进行了明确的区分 Swift语言的常量类型比C 语言的constants类型更加强大,语义更加明确. 常量和变量的区别是常量在设置或初始化后 ...
- 苹果新的编程语言 Swift 语言进阶(五)--控制流
Swift 语言支持C语言全部的控制语句.包含for 和while循环语句,if和switch条件语句,以及break和continue控制语句等. Swift 语言除了支持以上语句,还添加了一个f ...
随机推荐
- 动手试试Android Studio插件开发
由于业务关系,经常需要写一些表单页面,基本也就是简单的增删改查然后上传,做过几个页面之后就有点想偷懒了,这么低水平重复性的体力劳动,能不能用什么办法自动生成呢,查阅相关资料,发现android stu ...
- 微信小程序实例-摇一摇抽奖
概述 前面我们讲了如何开始微信小程序搭建和一些组件的介绍.微信小组件和微信小程序入门 微信小程序目录 为了更好的理解小程序和小程序开发,我们首先来看一下项目的目录. 首先看下根目录下的app.json ...
- 深度学习&机器学习资源汇总1
本篇博客的目地,是对工作学习过程中所遇所见的一些有关深度学习.机器学习的优质资源,作分类汇总,方便自己查阅,也方便他人学习借用. 主要会涉及一些优质的理论书籍和论文.一些实惠好用的工具库和开源库.一些 ...
- 有n个数,输出其中所有和为s的k个数的组合。
分析:此题有两个坑,一是这里的n个数是任意给定的,不一定是:1,2,3...n,所以可能有重复的数(如果有重复的数怎么处理?):二是不要求你输出所有和为s的全部组合,而只要求输出和为s的k个数的组合. ...
- 谷歌面试题:输入是两个整数数组,他们任意两个数的和又可以组成一个数组,求这个和中前k个数怎么做?
谷歌面试题:输入是两个整数数组,他们任意两个数的和又可以组成一个数组,求这个和中前k个数怎么做? 分析: "假设两个整数数组为A和B,各有N个元素,任意两个数的和组成的数组C有N^2个元素. ...
- Java基本语法-----java流程控制语句
1顺序语句 语句:使用分号分隔的代码称作为一个语句. 注意:没有写任何代码只是一个分号的时候,也是一条语句,称作空语句. 顺序语句就是按照从上往下的顺序执行的语句. 2判断(if-else) 在我们找 ...
- everything of people’s life can changed in their twenties
还记得三年前,独自背着行李,流浪远方,来到曾经只在地理课本上才熟悉的北国,带着好奇,带着期望,带着激动的心情,想感受毛爷爷当年霸气的北国风光,千里冰封的美丽,想知道北方的面条到底有多少种花样,想走进那 ...
- 如何查看App provision profile文件中的钥匙链访问组名称
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们因为某些原因希望安全的在多个App中共享一些信息,我们可以 ...
- Retrofit2.0 ,OkHttp3完美同步持久Cookie实现免登录(二)
原文出自csdn: http://blog.csdn.net/sk719887916/article/details/51700659: 通过对Retrofit2.0的<Retrofit 2.0 ...
- Android之自定义AlertDialog和PopupWindow实现(仿微信Dialog)
我们知道,在很多时候,我们都不用Android内置的一些控件,而是自己自定义一些自己想要的控件,这样显得界面更美观. 今天主要是讲自定义AlertDialog和popupWindow的使用,在很多需求 ...