美文网首页
Swift学习笔记十九之泛型

Swift学习笔记十九之泛型

作者: 克鲁德李 | 来源:发表于2017-01-12 11:13 被阅读0次

1、泛型:使用泛型能更清晰更简洁的表达代码意图

// 泛型所解决的问题
func swapTwoInts(a: inout Int, _ b: inout Int) { // 交换两个Int的值
let temp = a
a = b
b = temp
}
var someInt = 3
var anotherInt = 5
swapTwoInts(a: &someInt, &anotherInt)

// 但如果想交换String Double类型的数该怎样做呢?再写两个函数?

2、泛型函数:在函数名后面添加<T>,表示T是函数定义的占位类型;只要前后一致,别的字母也可以

func swapTwoValues<T>(a: inout T, _ b: inout T) { // 用T来替代实际类型,a和b是同一类型T
let temp = a
a = b
b = temp
}
swapTwoValues(a: &someInt, &anotherInt) // 在调用函数时,根据实际类型推断出T的类型

var StringA = "A"
var StringB = "B"
swapTwoValues(a: &StringA, &StringB) // 只要传入任何相同的类型都可以
print("StringA:(StringA),StringB:(StringB)") // StringA:B,StringB:A

3、类型参数
// 在上面的例子中占位类型T就是一个类型参数.
// 类型参数可以在函数名后面加一个占位类型, 并用尖括号括起来.例如< T >
// 类型参数设定后,就可以当做函数的参数类型使用了,可以是参数类型也可以是返回类型
// 当函数被调用的时候,类型参数会被转化为实际类型
// 类型参数可以有多个,可以写在尖括号中,用逗号隔开
// 通常使用单个字母T U V来命名类型参数,但也可以是以大写字母开头的字符串

4、泛型类型:能够让自定义类、结构体、和枚举适用于任何类型,类似于Array和Dictionary

struct Stack<Element> { // 模拟栈的操作过程的泛型集合类型
var items = Element // 使用Element为空数组进行初始化
mutating func push(item: Element) { // push的参数类型是Element
items.append(item)
}
mutating func pop() -> Element { // pop的返回值类型是Element类型
return items.removeLast()
}
}
var stackOfStrings = Stack<String>() // 在尖括号中写出栈中需要存储的数据类型
stackOfStrings.push(item: "A")
stackOfStrings.push(item: "B")
stackOfStrings.push(item: "C")
let fromTheTop = stackOfStrings.pop()
print(stackOfStrings.items) // ["A", "B"]

5、泛型类型的扩展:原类型中的类型参数在扩展中可以直接使用

extension Stack {
var topItem: Element? { // 返回栈顶元素的只读计算属性
return items.isEmpty ? nil : items[items.count - 1]
}
}
if let topItem = stackOfStrings.topItem {
print("topItem:(topItem)") // topItem:B
}

6、类型约束:swapTwoValues(::) 和Stack适用于任何类型,但有时我们需要对类型进行一些约束,这些约束可以是类型参数必须继承指定类,或者符合特定的协议或协议组合

class SomeClass {}
protocol SomeProtocol {}
// T的类型参数必须是SomeClass的子类,U的类型参数必须遵守SomeProtocol协议
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { // 类型约束语法
}

// 根据字符串查找在数组中的索引
func findIndex<T: Equatable>(of valueToFind: T, in array:[T]) -> Int? {
for (index, value) in array.enumerated() {
// 为T增加一个Equatable协议,遵循该协议的类型必须实现等式符和不等符号.才可以对两个类型进行比较
if value == valueToFind {
return index
}
}
return nil
}

let doubleIndex = findIndex(of: 5.0, in: [3.2, 1.0, 5.0, 5,6]) // 2
let stringIndex = findIndex(of: "O", in: ["V", "D", "E", "O"]) // 3

7、类型的关联:关联类型为协议中某个类型提供别名
protocol Container { // 定义一个Container协议
associatedtype ItemType // 通过associatedtype关键词来定义一个关联类型
mutating func append(item: ItemType) // 添加一个新的元素到容器里
var count: Int { get } // 获取容器中的元素个数
subscript(i: Int) -> ItemType { get } // 通过索引获取容器中的元素
}

struct NewStack<Element>: Container {
var items = Element
mutating func push(item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
mutating func append(item: Element) {
self.push(item: item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Element { // swift会自动推断Element就是ItemType类型
return items[i] // 不需要再去指定ItemType类型为Element类型
}
}
8、where子句:为泛型的类型参数做一些约束

protocol Container { // 定义一个Container协议
associatedtype ItemType // 通过associatedtype关键词来定义一个关联类型
mutating func append(item: ItemType) // 添加一个新的元素到容器里
var count: Int { get } // 获取容器中的元素个数
subscript(i: Int) -> ItemType { get } // 通过索引获取容器中的元素
}

struct NewStack<Element>: Container {
var items = Element
mutating func push(item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
mutating func append(item: Element) {
self.push(item: item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Element { // swift会自动推断Element就是ItemType类型
return items[i] // 不需要再去指定ItemType类型为Element类型
}
}

相关文章

  • Swift学习笔记十九之泛型

    1、泛型:使用泛型能更清晰更简洁的表达代码意图 // 泛型所解决的问题func swapTwoInts(a: in...

  • 《Swift从入门到精通》(十九):泛型

    泛型(学习笔记) 环境Xcode 11.0 beta4 swift 5.1 泛型可解决的问题如两个 Int 类型交...

  • swift 泛型

    Swift-泛型学习和实例总结 - Mazy's Blog - CSDN博客 Swift中的泛型 - 简书

  • Swift学习笔记-泛型

    泛型能让我们使用的类型和函数使用未知的类型,许多内置类型,例如可空类型,数组和字典都是用泛型实现的。 泛型类型 下...

  • Swift学习笔记--泛型

    泛型 原文链接 泛型代码让你能根据你所定义的要求写出可以用于任何类型的灵活的、可复用的函数。你可以编写出可复用、意...

  • swift 笔记 之 泛型

    //泛型//泛型代码可以让你写出根据自我需求定义、适用于任何类型的 灵活且可重用的函数和类型//可以避免重复的代码...

  • Swift学习之泛型

    泛型能够让开发者编写自定义需求已经任意类型的灵活可用的的函数和类型。能够让我们避免重复的代码。用一种清晰和抽象的方...

  • Swift学习之泛型

    swapTwoInts(::) 函数很实用,但是它只能用于 Int 值。如果你想交换两个 String 值,或者两...

  • Swift-泛型笔记

    Swift 泛型 Swift 提供了泛型让你写出灵活且可重用的函数和类型。 Swift 标准库是通过泛型代码构建出...

  • [ WWDC2018 ] - Swift 泛型 Swift Ge

    Swift 泛型历史 我们首先来回顾一下 Swift 中对于泛型支持的历史变更,看看现在在 Swift 中,泛型都...

网友评论

      本文标题:Swift学习笔记十九之泛型

      本文链接:https://www.haomeiwen.com/subject/qljdbttx.html