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

 更新时间:2022年06月17日 16:41:01   作者:Swift社区  
类型占位符是swift5.6中引⼊的⼀个新功能,在处理稍微复杂的通⽤类型时,它可能真的很有用,这篇文章主要给大家介绍了关于Swift类型占位符的相关资料,需要的朋友可以参考下

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图像处理之优化照片

    Core Image能通过分析图片的各个属性,人脸的区域等进行自动优化图片。我们只需要调用autoAdjustmentFiltersWithOptions这个API方法获取各个自动增强滤镜来优化图片即可。不管是人物照片还是风景照均可增强效果
    2015-11-11
  • Swift中非可选的可选值类型处理方法详解

    Swift中非可选的可选值类型处理方法详解

    Optional是Objective-C没有的数据类型,是苹果引入到Swift语言中的全新类型,它的特点就和它的名字一样:可以有值,也可以没有值,当它没有值时,就是nil。下面这篇文章主要给大家介绍了关于Swift中非可选的可选值类型处理方法的相关资料,需要的朋友可以参考下。
    2017-11-11
  • Swift 3.0基础学习之下标

    Swift 3.0基础学习之下标

    这篇文章主要介绍了Swift 3.0基础学习之下标的相关资料,文中介绍的非常详细,对大家学习或者使用swift具有一定的参考价值,需要的朋友下面来一起看看吧。
    2017-03-03
  • Swift 4中一些实用的数组技巧小结

    Swift 4中一些实用的数组技巧小结

    这篇文章主要给大家分享了关于Swift 4中一些实用的数组技巧,文中通过示例代码介绍的介绍的非常详细,对大家学习或者使用swift具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-03-03
  • Swift函数提前返回实例详解

    Swift函数提前返回实例详解

    函数相当重要的,下面这篇文章主要给大家介绍了关于Swift函数提前返回的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09
  • switch实现一个两数的运算代码示例

    switch实现一个两数的运算代码示例

    这篇文章主要介绍了switch实现一个两数的运算代码示例,需要的朋友可以参考下
    2017-06-06
  • Swift中的类class与结构体struct体学习笔记

    Swift中的类class与结构体struct体学习笔记

    和C++一样,Swfit中同时拥有类与结构体,能够充分满足开发者面向对象和面向过程编程的需求,这里我们就来看一下Swift中的类class与结构体struct体学习笔记
    2016-07-07
  • Swift使用transform 实现重复平移动画效果

    Swift使用transform 实现重复平移动画效果

    这篇文章主要介绍了Swift使用transform 实现重复平移动画效果,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • Swift中的高阶函数功能作用示例详解

    Swift中的高阶函数功能作用示例详解

    这篇文章主要为大家介绍了Swift中的高阶函数功能作用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Swift3.0 GCD定时器的使用DEMO

    Swift3.0 GCD定时器的使用DEMO

    这篇文章主要介绍了Swift3.0 GCD定时器的使用,实现倒计时,UIDatePicker的使用, 仿写一个活动倒计时的DEMO,需要的朋友可以参考下
    2017-02-02

最新评论