解析Swift中的泛型支持与使用

一、以泛型为参数的函数

泛型是Swift语言强大的核心,泛型是对类型的抽象,使用泛型开发者可以更加灵活方便的表达代码意图。我们知道,有参函数的参数必须有一个明确的参数类型,有些时候开发者会遇到这样一种情况,编写一个函数用于交换两个变量的值,由于变量有类型之分,实现相同的功能,可能需要重载成多个函数来实现,这大大浪费了开发成本,使用泛型,可以完美的解决这个问题,示例代码如下:

func exchange<T>(inout param1:T,inout param2:T){
  let tmp = param1
  param1 = param2
  param2 = tmp
}
var p1 = "15"
var p2 = "40"
exchange(&p1, param2: &p2)

上面的方法可以实现对任意相同类型变量的交换,函数参数中使用泛型,需要在函数名后的<>中定义参数占位符,如有多个参数占位符,用逗号隔开即可。

二、泛型在类型中的应用

泛型除了可以作为函数的参数、返回值外,在定义类型时,灵活应用泛型也可以解决很多十分棘手的问题,例如实现一个栈结构的集合类型,示例代码如下:

struct Stack<ItemType> {
  var items:[ItemType] = []
  mutating func push(param:ItemType) {
    self.items.append(param)
  }
  mutating func pop()->ItemType{
    return self.items.removeLast()
  }
}
//整型栈
var obj1 = Stack<Int>()
obj1.push(1)
obj1.pop()
//字符串栈
var obj2 = Stack<String>()
obj2.push("HS")
obj2.pop()

在对使用了泛型的类型进行扩展时,不需要在使用<>进行泛型的定义,直接使用原定义的泛型占位符即可,示例如下:

extension Stack{
  func getArray() -> [ItemType] {
    return items
  }
}

有时候,开发者需要对泛型进行一些约束,例如只允许此泛型是继承自某个类或者实现了某个协议,示例代码如下:

class MyClass {

}
//只有MyClass的子类可以进行Stack栈的创建
struct Stack<ItemType:MyClass> {
  var items:[ItemType] = []
  mutating func push(param:ItemType) {
    self.items.append(param)
  }
  mutating func pop()->ItemType{
    return self.items.removeLast()
  }
}

在协议中,可以使用另一种方式来进行泛型编程,使用associatedtype关键字可以进行类型关联,示例如下:

protocol MyProtocol {
  //实现协议时才指定类型
  associatedtype ItemType
  var param:ItemType {get set}
}
class MyClass:MyProtocol {
  //由于Swift可以自动识别类型 这是MyProtocol中的ItemType为Int
  var param: Int = 0
}

三、泛型与where子句的结合使用

使用where子句可以对泛型进行更加严格约束,使其符合开发者需要的逻辑,示例如下:

//T和C都要遵守整型协议
class MyClassTwo<T,C where T:IntegerType,C:IntegerType> {
  var param1:T
  var param2:C
  init(param1:T,param2:C){
    self.param1=param1
    self.param2=param2

  }
}

var obj3 = MyClassTwo(param1: 1, param2: 1)
(0)

相关推荐

  • Swift编程中的泛型解析

    泛型代码可以让你写出根据自我需求定义.适用于任何类型的,灵活且可重用的函数和类型.它可以让你避免重复的代码,用一种清晰和抽象的方式来表达代码的意图.   泛型是 Swift 强大特征中的其中一个,许多 Swift 标准库是通过泛型代码构建出来的.事实上,泛型的使用贯穿了整本语言手册,只是你没有发现而已.例如,Swift 的数组和字典类型都是泛型集.你可以创建一个Int数组,也可创建一个String数组,或者甚至于可以是任何其他 Swift 的类型数据数组.同样的,你也可以创建存储任何指定类型的字

  • 初步理解Swift中的泛型

    如果你已经动手写过Swift的程序,相信你已经了解了Swift语言的知识,比如如何写类(class)和结构体(struct).但Swift可没这么简单,呵呵呵.这篇教程主要讲述Swift的一个强力的特性:泛型.这个特性在很多程序设计语言里都非常受欢迎. 对于类型安全(type-safe)语言,一个常见的问题就是如何编写适用于多种类型输入的程序.想象一下,两个整型数相加和两个浮点数相加的程序看起来应该非常类似,甚至一模一样才对.唯一的区别就是变量的类型不同. 在强类型语言中,你需要去定义诸如add

  • 解析Swift中的泛型支持与使用

    一.以泛型为参数的函数 泛型是Swift语言强大的核心,泛型是对类型的抽象,使用泛型开发者可以更加灵活方便的表达代码意图.我们知道,有参函数的参数必须有一个明确的参数类型,有些时候开发者会遇到这样一种情况,编写一个函数用于交换两个变量的值,由于变量有类型之分,实现相同的功能,可能需要重载成多个函数来实现,这大大浪费了开发成本,使用泛型,可以完美的解决这个问题,示例代码如下: func exchange<T>(inout param1:T,inout param2:T){ let tmp = p

  • 深入解析Swift中switch语句对case的数据类型匹配的支持

    Swift可以对switch中不同数据类型的值作匹配判断: var things = Any[]() things.append(0) things.append(0.0) things.append(42) things.append(3.14159) things.append("hello") things.append((3.0, 5.0)) things.append(Movie(name:"Ghostbusters", director:"Iv

  • 在Swift中使用KVO的细节以及内部实现解析(推荐)

    KVO是什么? KVO 是 Objective-C 对观察者设计模式的一种实现.[另外一种是:通知机制(notification),详情参考:iOS 趣谈设计模式--通知]: KVO提供一种机制,指定一个被观察对象(例如A类),当对象某个属性(例如A中的字符串name)发生更改时,对象会获得通知,并作出相应处理:[且不需要给被观察的对象添加任何额外代码,就能使用KVO机制] 在MVC设计架构下的项目,KVO机制很适合实现mode模型和view视图之间的通讯. 例如:代码中,在模型类A创建属性数据

  • 解析Swift语言面相对象编程中的继承特性

    取大于形态的能力被定义为继承.一般一个类可以从另一个类继承属性和方法.类可以进一步划分到子类和超类. 子类:当一个类从另一个类继承属性,方法和功能被称为子类 超类:类包含属性,方法和功能被其它类继承称为超类 Swift 中类包含父类和调用访问方法,属性,功能和重写方法.另外,属性观察者也用于添加属性和修改所存储的或计算的特性的方法. 基类 一个类如果不从其它类继承方法,属性或功能,那么它被称为"基类". 复制代码 代码如下: classStudDetails{var stname:St

  • 深入解析Swift编程中的构造方法

    一.引言 构造方法是一个类创建对象最先也是必须调用的方法,在Objective-C中,开发者更习惯称这类方法为初始化方法.在Objective-C中的初始化方法与普通函数相比除了要以init抬头外并无太严格的分界,而在Swift语言体系中,构造方法与普通的方法分界十分严格,从格式写法上就有不同,普通方法函数要以func声明,构造方法统一为init命名,不需要func关键字声明,不同的构造方法采用方法重载的方式创建. 二.构造方法的复写与重载 在Objective-C中,不同的初始化方法就是不同的

  • 深入解析Swift编程中枚举类型的相关使用

    枚举是由用户定义的数据类型的一组相关值.关键字 enum 用来定义枚举数据类型. 枚举功能 枚举在 swift 也类似于 C 和 Objective C 中结构类型 它是在一个类中声明,其值是通过该类的实例来访问 初始成员值是用枚举初始化定义的 其功能也扩展确保标准的协议功能 语法 枚举引入 enum 关键字和一对大括号内将它们定义: 复制代码 代码如下: enum enumname {    // enumeration values are described here } 例如,可以为星期

  • Swift中的命名空间详解

    前言 Objective-C 一个一直以来令人诟病的地方就是没有命名空间,在应用开发时,所有的代码和引用的静态库最终都会被编译到同一个域和二进制中.这样的后果是一旦我们有重复的类名的话,就会导致编译时的冲突和失败.为了避免这种事情的发生,Objective-C 的类型一般都会加上两到三个字母的前缀,比如 Apple 保留的 NS 和 UI 前缀,各个系统框架的前缀 SK (StoreKit),CG (CoreGraphic) 等.Objective-C 社区的大部分开发者也遵守了这个约定,一般都

  • 深入讲解Swift中的模式匹配

    模式匹配 模式匹配是 Swift 中非常常见的一种编程模式,使用模式匹配,可以帮助我们写出简明.清晰以及易读的代码,使我们的代码变得简洁而强大. 条件判断中的模式匹配 条件判断是我们使用最普遍的流程控制,在 Swift 中,只能接受 Bool 类型的值作为条件体:除了直接判断 Bool 值之外,我们还能使用使用条件语句进行可选绑定,这在我们开发中是非常常用的方式. 匹配枚举值 在 Swift 中,创建的枚举类型默认是不可比较的(没有实现Comparable协议),这就意味着我们不能直接使用==操

  • Swift中风味各异的类型擦除实例详解

    目录 前言 什么时候需要类型擦除? 通用包装器类型擦除 闭包类型擦除 结语 前言 Swift的总体目标是既强大到可以用于底层系统编程,又足够容易让初学者学习,这有时会导致相当有趣的情况——当Swift的类型系统的力量要求我们部署相当高级的技术来解决乍一看可能更微不足道的问题. 大多数Swift开发人员会在某一时刻或另一时刻(通常是马上,而不是日后)会遇到这样一种情况,即需要某种形式的类型擦除才能引用通用协议.从本周开始,让我们看一下是什么使类型擦除在Swift中成为必不可少的技术,然后继续探索实

随机推荐