Swift泛型Generics浅析讲解

 更新时间:2022年08月24日 08:37:15   作者:扑腾的蛾子  
泛型代码让你能根据你所定义的要求,写出可以用于任何类型的灵活的、可复用的函数。泛型是 Swift 最强大的特性之一,很多 Swift 标准库是基于泛型代码构建的

泛型(Generics)

1、泛型可以将类型参数化,提高代码复用率,减少代码量

func swapValue<T>(_ a: inout T, _ b: inout T) -> Void {
    (a, b) = (b, a)
}
var fn: (inout Int, inout Int) -> () = swapValue

class Stack<E> {
    var elements = [E]()
    func push(_ element: E) -> Void {
        elements.append(element)
    }
    func pop() -> E {
        elements.removeLast()
    }
    func top() -> E {
        elements.last!
    }
    func size() -> Int {
        elements.count
    }
}
var intStack = Stack<Int>()
var stringStack = Stack<String>()
var anyStack = Stack<Any>()
class SubStack<E>: Stack<E> {
}
struct Stack<E> {
    var elements = [E]()
    mutating func push(_ element: E) {
        elements.append(element)
    }
    mutating func pop() -> E {
        elements.removeLast()
    }
    func top() -> E {
        elements.last!
    }
    func size() -> Int {
        elements.count
    }
}

汇编分析泛型的实现原理

通过汇编我们可以看到两次调用的swapValues方法的地址是相同的,也就是说是相同的方法,汇编中有关于metadata的信息,所以推测Swift中的泛型是通过对元数据的处理实现的。

关联类型(Associated Type)

1、关联类型的作用:给协议中用到的类型定义一个占位名称

2、协议中可以拥有多个关联类型

protocol Stackable {
    associatedtype Element
    mutating func push(_ element: Element)
    mutating func pop() -> Element
    func top() -> Element
    func size() -> Int
}
class StringStack: Stackable {
//    typealias Element = String 可写可不写
    var elements = [String]()
    func push(_ element: String) -> Void {
        elements.append(element)
    }
    func pop() -> String {
        elements.removeLast()
    }
    func top() -> String {
        elements.last!
    }
    func size() -> Int {
        elements.count
    }
}

类型约束

protocol Runnable {}
class Person {}
func swapValues<T: Person & Runnable>(_ a: inout T, _ b: inout T) -> Void {
    (a, b) = (b, a)
}

更多的约束

func equal<S1: Stackable, S2: Stackable>(_ s1: S1, _ s2: S2) -> Bool
where S1.Element == S2.Element, S1.Element: Hashable
{
    return false
}

协议类型的注意点

protocol Runnable {}
class Person: Runnable {}
class Car: Runnable {}
func getObject(_ type: Int) -> Runnable {
    if type == 0 {
        return Person()
    }
    return Car()
}
var r1 = getObject(0)
var r2 = getObject(1)

1、如果协议中有associatedtype,那么会有类型识别不了的问题,以下代码会报错

protocol Runnable {
    associatedtype Speed
    var speed: Speed {
        get
    }
}
class Person: Runnable {
    var speed: Double {
        0.0
    }
}
class Car: Runnable {
    var speed: Int {
        0
    }
}
func getObject(_ type: Int) -> Runnable {
    if type == 0 {
        return Person()
    }
    return Car()
}

泛型解决

解决方案1:使用泛型

protocol Runnable {
    associatedtype Speed
    var speed: Speed {
        get
    }
}
class Person: Runnable {
    var speed: Double {
        0.0
    }
}
class Car: Runnable {
    var speed: Int {
        0
    }
}
func getObject<T: Runnable>(_ type: Int) -> T {
    if type == 0 {
        return Person() as! T
    }
    return Car() as! T
}
var r1: Person = getObject(0)
var r2: Car = getObject(1)

不透明类型(Opaque Type)

1、解决方案2:使用some关键字声明一个不透明类型

func getObject(_ type: Int) -> some Runnable {
    return Car()
}

2、some限制只能返回一种类型

some

1、some除了用在返回值类型上,一般还可以用在属性类型上

protocol Runnable {
    associatedtype Speed
}
class Dog: Runnable {
    typealias Speed = Double
}
class Person {
    var pet: some Runnable {
        return Dog()
    }
}

到此这篇关于Swift泛型Generics浅析讲解的文章就介绍到这了,更多相关Swift Generics内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Swift编程中的方法与属性的概念

    详解Swift编程中的方法与属性的概念

    这篇文章主要介绍了Swift编程中的方法与属性的概念,是Swift入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11
  • swift3.0键盘弹起遮挡输入框问题的解决方案

    swift3.0键盘弹起遮挡输入框问题的解决方案

    这篇文章主要介绍了swift3.0键盘弹起遮挡输入框问题的解决方案,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-11-11
  • 深入浅出的聊聊Swift高阶函数

    深入浅出的聊聊Swift高阶函数

    函数式编程就是高阶函数编程的应用,所以要熟练掌握基础的高阶函数是必须的filter、map、reduce、flatmap就是必备的高阶函数,这篇文章主要给大家介绍了关于Swift高阶函数的相关资料,需要的朋友可以参考下
    2021-09-09
  • switch循环所支持的数据类型案例分析

    switch循环所支持的数据类型案例分析

    这篇文章主要介绍了switch循环所支持的数据类型,本文通过实际案例讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-06-06
  • Swift中常量和变量的区别与声明详解

    Swift中常量和变量的区别与声明详解

    Swift语言同样和Java和OC等语言一样是同样是需要声明常量和变量的,下面就让我们来学习一下Swift的常量和变量。这篇文章主要给大家介绍了关于Swift中常量和变量的区别与声明的相关资料,需要的朋友可以参考下。
    2017-11-11
  • Swift教程之方法详解

    Swift教程之方法详解

    这篇文章主要介绍了Swift教程之方法详解,方法是关联到一个特定类型的函数,类、结构、枚举所有可以定义实例方法,封装特定任务和功能处理给定类型的一个实例,需要的朋友可以参考下
    2015-01-01
  • Swift利用CoreData实现一个上班签到的小工具

    Swift利用CoreData实现一个上班签到的小工具

    这篇文章主要给大家介绍了关于Swift利用CoreData实现一个上班签到小工具的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-12-12
  • 初步理解Swift中的泛型

    初步理解Swift中的泛型

    这篇文章主要介绍了初步理解Swift中的泛型,是Swift入门学习中的基础知识,需要的朋友可以参考下
    2015-07-07
  • RxSwift使用技巧之过滤操作详解

    RxSwift使用技巧之过滤操作详解

    RxSwift的目的是让让数据/事件流和异步任务能够更方便的序列化处理,能够使用Swift进行响应式编程,下面这篇文章主要给大家介绍了关于RxSwift使用技巧之过滤操作的相关资料,需要的朋友可以参考下。
    2017-09-09
  • Swift的开发环境搭建以及基本语法详解

    Swift的开发环境搭建以及基本语法详解

    这篇文章主要介绍了Swift的开发环境搭建以及基本语法详解,是Swift入门学习中的基础知识,需要的朋友可以参考下
    2015-11-11

最新评论