详细讲解Swift中的类型占位符

 更新时间:2022年06月17日 16:41:01   作者:Swift社区  
类型占位符是swift5.6中引?的?个新功能,在处理稍微复杂的通?类型时,它可能真的很有用,这篇文章主要给大家介绍了关于Swift类型占位符的相关资料,需要的朋友可以参考下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

Swift 的类型推断能力从一开始就是语言的核心部分,它极大地减少了我们在声明有默认值的变量和属性时手动指定类型的工作。例如,表达式var number = 7不需要包含任何类型注释,因为编译器能够推断出值7是一个Int,我们的number变量应该被相应的类型化。

作为 Xcode 13.3 的一部分而一起发布的 Swift 5.6,通过引入 "类型占位符(type placeholders) "的概念,继续扩展这些类型推理能力,这在处理集合和其他通用类型时非常有用。

例如,假设我们想创建一个Combine里面具有默认整数值的 CurrentValueSubject的实例。关于如何做到这一点的初步想法可能是简单地将我们的默认值传递给该主体的初始化器,然后将结果存储在本地的一个let声明的属性中(就像创建一个普通的Int值时一样)。然而,这样做会给我们带来以下编译器错误:

// Error: "Generic parameter 'Failure' could not be inferred"
// Error: “无法被推断出泛型的`Failure`参数 ”
let counterSubject = CurrentValueSubject(0)

这是因为CurrentValueSubject是一个泛型类型,实例化时不仅需要Output类型,还需要Failure类型——这是该主体能够抛出的错误类型。

因为我们不希望我们的主体在这种情况下抛出任何错误,所以我们会给它一个Failure类型的值Never(这是在 Swift 中使用 Combine 的一个常见惯例)。但为了做到这一点,在 Swift 5.6 之前,我们需要明确地指定我们的Int输出类型——像这样:

let counterSubject = CurrentValueSubject<Int, Never>(0)

不过从 Swift 5.6 开始,这种情况就不存在了——因为我们现在可以使用一个类型占位符来表示我们主体的Output类型,这让我们再次利用编译器为我们自动推断出该类型,就像在声明一个普通的Int值一样:

let counterSubject = CurrentValueSubject<_, Never>(0)

这很好,但可以说这并不是 swift 里面很大的改进。毕竟,我们用_代替Int只是节省了两个字符,而且手动指定像Int这样的简单类型也不是一开始就有问题的。

**但现在让我们看看这个功能如何扩展到更复杂的类型,这是它真正开始发光的地方。**例如,假设我们的项目包含以下函数,让我们加载一个用户注解的PDF文件:

func loadAnnotatedPDF(named: String) -> Resource<PDF<UserAnnotations>> {
    ...
}

上面的函数使用了一个相当复杂的泛型作为它的返回类型,这可能是因为我们需要在多个地方中重复使用我们的Resource类型,也因为我们选择了使用*幻象类型*来指定我们当前处理的是哪种PDF。

现在让我们看看,如果我们在创建主体时调用上述函数,而不是仅仅使用一个简单的整数,那么我们之前基于CurrentValueSubject的代码会是什么样子:

// Before Swift 5.6:
let pdfSubject = CurrentValueSubject<Resource<PDF<UserAnnotations>>, Never>(
    loadAnnotatedPDF(named: name)
)

// Swift 5.6:
let pdfSubject = CurrentValueSubject<_, Never>(
    loadAnnotatedPDF(named: name)
)

这是一个相当大的改进啊 基于 Swift 5.6 的版本不仅为我们节省了一些输入,而且由于 pdfSubject 的类型现在完全来自 loadAnnotatedPDF 函数,这可能会使该函数(及其相关代码)的迭代更加容易——因为如果我们改变该函数的返回类型,需要更新的手动类型注释将减少。

不过,值得指出的是,在上述情况下,还有另一种方法可以利用Swift的类型推理能力——那就是使用类型别名,而不是类型占位符。例如,我们可以在这里定义一个UnfailingValueSubject类型别名,我们可以用它来轻松地创建不会产生任何错误的主体:

typealias UnfailingValueSubject<T> = CurrentValueSubject<T, Never>

有了上述内容,我们现在就可以在没有任何泛型注解的情况下创建我们的pdfSubject了——因为编译器能够推断出T指的是什么类型,而且失败类型Never已经被硬编码到我们的新类型别名中:

let pdfSubject = UnfailingValueSubject(loadAnnotatedPDF(named: name))

但这并不意味着类型别名在通常情况下都比类型占位符好,因为如果我们要为每种特定情况定义新的类型别名,那么这也会使我们的代码库变得更加复杂。有时,在内联中指定所有的东西(比如使用类型占位符时)绝对是个好办法,因为这可以让我们定义完全独立的表达式。

在我们总结之前,让我们也来看看类型占位符是如何与集合字面量(literals)一起使用的——例如在创建一个字典时。在这里,我们选择手动指定我们的字典的 Key 类型(为了能够使用点语法来指代枚举的各种情况),同时为该字典的值使用一个类型占位符:

enum UserRole {
    case local
    case remote
}

let latestMessages: [UserRole: _] = [
    .local: "",
    .remote: ""
]

这就是类型占位符——Swift 5.6 中引入的一个新功能,在处理稍微复杂的通用类型时,它可能真的很有用。但值得指出的是,这些占位符只能在调用站点使用,而不是在指定函数或计算属性的返回类型时使用。

总结

到此这篇关于Swift类型占位符的文章就介绍到这了,更多相关Swift类型占位符内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • Swift中添加双击手势识别器

    Swift中添加双击手势识别器

    在这次IOS应用开发教程中,我们打算实现手势识别。正如你所知道的,IOS支持大量的手势操作,它们能提供了很好的应用控制和出色用户体验。
    2019-08-08
  • Swift 3.0基础学习之闭包

    Swift 3.0基础学习之闭包

    Swift引进了闭包的概念,这个与object-c的block类似,使用过block的话都知道有多方便,所以开始学Swift,先要把闭包学会,后面使用会很频繁。下面这篇文章主要介绍了Swift 3.0基础学习之闭包的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-03-03
  • Swift 3中使用FMDB遇到的问题与解决方法

    Swift 3中使用FMDB遇到的问题与解决方法

    相信大家都熟悉OC使用FMDB第三方库,进行数据库操作,增、删、改、查,但最近在Swift 3中使用FMDB遇到了一些问题,下面这篇文章主要给大家介绍了关于在Swift 3中使用FMDB遇到的问题与解决方法,需要的朋友可以参考下。
    2017-07-07
  • swift中利用runtime交换方法的实现示例

    swift中利用runtime交换方法的实现示例

    这篇文章主要给大家介绍了关于swift中利用runtime交换方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-05-05
  • iOS开发中Swift 指纹验证功能模块实例代码

    iOS开发中Swift 指纹验证功能模块实例代码

    本文给大家分享ios调用touchid代码块,非常不错,具有参考借鉴价值,需要的朋友参考下把
    2017-03-03
  • swift中的@UIApplicationMain示例详解

    swift中的@UIApplicationMain示例详解

    这篇文章主要给大家介绍了关于swift中@UIApplicationMain的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-12-12
  • Swift实现堆排序算法的代码示例

    Swift实现堆排序算法的代码示例

    堆排序(HeapSort)是一树形选择排序,堆排序的时间复杂度O(nlogn),这里我们来看一下Swift实现基堆排序算法的代码示例,首先对堆排序算法的基本概念作一个了解:
    2016-06-06
  • Swift3迁移至Swift4可能遇到的问题小结

    Swift3迁移至Swift4可能遇到的问题小结

    每当看到新的编程语言我总是会有相当大的兴趣,所以下面这篇文章主要给大家介绍了关于Swift3迁移至Swift4可能遇到的问题,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面来一起学习学习吧
    2018-06-06
  • Swift使用enum抹平数组元素差异实例详解

    Swift使用enum抹平数组元素差异实例详解

    这篇文章主要为大家介绍了Swift使用enum抹平数组元素差异实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Swift中初始化方法的顺序介绍

    Swift中初始化方法的顺序介绍

    这篇文章主要介绍了Swift中初始化方法的顺序介绍,本文介绍的是了类的初始化方法,需要的朋友可以参考下
    2015-01-01

最新评论

?


http://www.vxiaotou.com