Swift学习笔记22——泛型(Generics)
2015-10-13 18:05
423 查看
泛型函数
当我们写一个函数的时候,一般都会指明参数的类型。比如下面两个实现交换变量的函数(摘自官方文档)
所以有了泛型这个概念,泛型就是模糊的类型。当我们函数的功能实现和具体类型没关系的时候,就可以使用泛型。
有了泛型,我们可以将上面实现两个变量交换的功能用一个方法完成,这个方法可以用于不同的数据类型
泛型的函数调用方法和普通函数是一样的。下面创建了两个Animal实例,然后使用刚刚定义的函数交换数据。
泛型类型
定义一个类型,但是它可以对不同类型的数据进行操作。比如Array和Dictionary这两个集合结构体,他们可以装不同类型的数据,这就是泛型类型。
官方文档给我们展示了一个泛型类型的栈,它使用Array来实现.
然后在创建这种泛型类型实例的时候,我们必须指定所属的类型。
泛型约束
我们可以对泛型进行约束,让他们必须遵守某些协议,官方文档语法如下
同时还可以添加where约束符再对泛型进行限制
关联类型
在定义协议的时候,我们可能需要定义一个或多个类型作为我们协议的一部分。而这些类型是不确定的,只有到具体的类实现协议的时候才能确定,这个时候我们可以使用关联类型来实现。所谓的关联类型就是一个占位符,等到具体实现协议的时候才知道它具体是什么类型。官方例子如下:
然后在实现协议的时候,我们可以指定ItemType具体是什么类型
同时又因为有Swift的类型判断机制,所以我们在实现了协议的其他方法之后,编译器会自动判断关联类型是什么,不需要我们显式地指定。所以上面代码指定关联类型为Int的那行可以删去。
泛型OC是不支持的,但是java支持。使用泛型能给编程带来很大的便利。
引用文档
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html#//apple_ref/doc/uid/TP40014097-CH26-ID179
当我们写一个函数的时候,一般都会指明参数的类型。比如下面两个实现交换变量的函数(摘自官方文档)
func swapTwoInts(inout a: Int, inout _ b: Int) { let temporaryA = a a = b b = temporaryA }上面的只是限于交换整形。但是如果我们相对Double或Float类型,甚至是任何类型的数据实现交换的功能,我们都要分别写一个函数。这是无比麻烦的。
所以有了泛型这个概念,泛型就是模糊的类型。当我们函数的功能实现和具体类型没关系的时候,就可以使用泛型。
有了泛型,我们可以将上面实现两个变量交换的功能用一个方法完成,这个方法可以用于不同的数据类型
func swapTwoValues<T>(inout a: T, inout _ b: T) { let temporaryA = a a = b b = temporaryA }主要的语法就是上面的<T>,这个T就是代表某个类型,但是没有指明具体是哪种类型。而且这个T,可以换成你希望的标示符,只要不是关键字。并且一般要求单词的首字母要大写,比如Element、Value等。而且能指定多个类型,见下面的类型约束
泛型的函数调用方法和普通函数是一样的。下面创建了两个Animal实例,然后使用刚刚定义的函数交换数据。
var cat = Animal() cat.life = 1 var dog = Animal() dog.life = 2 swapTwoValues(&cat, &dog) print(cat.life) // 2 print(dog.life) // 1
泛型类型
定义一个类型,但是它可以对不同类型的数据进行操作。比如Array和Dictionary这两个集合结构体,他们可以装不同类型的数据,这就是泛型类型。
官方文档给我们展示了一个泛型类型的栈,它使用Array来实现.
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>() stackOfStrings.push("uno")
泛型约束
我们可以对泛型进行约束,让他们必须遵守某些协议,官方文档语法如下
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { // function body goes here }
同时还可以添加where约束符再对泛型进行限制
func someFunction<T: SomeClass, U: SomeProtocol where T.someItem == U, U.someItem: SomeClass2>(someT: T, someU: U) { // function body goes here }
关联类型
在定义协议的时候,我们可能需要定义一个或多个类型作为我们协议的一部分。而这些类型是不确定的,只有到具体的类实现协议的时候才能确定,这个时候我们可以使用关联类型来实现。所谓的关联类型就是一个占位符,等到具体实现协议的时候才知道它具体是什么类型。官方例子如下:
protocol Container { typealias ItemType mutating func append(item: ItemType) var count: Int { get } subscript(i: Int) -> ItemType { get } }
然后在实现协议的时候,我们可以指定ItemType具体是什么类型
struct IntStack: Container { // original IntStack implementation var items = [Int]() mutating func push(item: Int) { items.append(item) } mutating func pop() -> Int { return items.removeLast() } // conformance to the Container protocol typealias ItemType = Int mutating func append(item: Int) { self.push(item) } var count: Int { return items.count } subscript(i: Int) -> Int { return items[i] } }
同时又因为有Swift的类型判断机制,所以我们在实现了协议的其他方法之后,编译器会自动判断关联类型是什么,不需要我们显式地指定。所以上面代码指定关联类型为Int的那行可以删去。
泛型OC是不支持的,但是java支持。使用泛型能给编程带来很大的便利。
引用文档
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Generics.html#//apple_ref/doc/uid/TP40014097-CH26-ID179
相关文章推荐
- 基于swift的UItableview
- swift中计算图片显示方式返回的尺寸
- [swift]可选类型
- 【Swift】iOS开发小技巧(一)
- Swift的基本类型和流程控制
- swift 关键字guard 计算属性
- swift学习笔记之函数(一)
- Swift基础
- Swift2.1 语法指南——析构过程
- swift 与 OC之间的关系
- Swift2.1 语法指南——构造过程
- Start Developing iOS Apps (Swift) 学习笔记 (1)
- Swift2.0单例的写法
- [Swift]UIKit学习之UILabel的用法
- [Swift]UIKit学习之UIButton的用法
- [Swift]UIKit学习之UISegSmentedControl的用法
- Swift中的问号?和感叹号!
- Swift可选值Optionals
- swift基础--数组、字典
- swift基础--字符串