热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Swift类型占位符

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

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(0)

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

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

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

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

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

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

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

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

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

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

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

typealias UnfailingValueSubject = CurrentValueSubject

有了上述内容,我们现在就可以在没有任何泛型注解的情况下创建我们的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 中引入的一个新功能,在处理稍微复杂的通用类型时,它可能真的很有用。但值得指出的是,这些占位符只能在调用站点使用,而不是在指定函数或计算属性的返回类型时使用。

总结


推荐阅读
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 分享一款基于Java开发的经典贪吃蛇游戏实现
    本文介绍了一款使用Java语言开发的经典贪吃蛇游戏的实现。游戏主要由两个核心类组成:`GameFrame` 和 `GamePanel`。`GameFrame` 类负责设置游戏窗口的标题、关闭按钮以及是否允许调整窗口大小,并初始化数据模型以支持绘制操作。`GamePanel` 类则负责管理游戏中的蛇和苹果的逻辑与渲染,确保游戏的流畅运行和良好的用户体验。 ... [详细]
  • 本文介绍了如何在 Spring 3.0.5 中使用 JdbcTemplate 插入数据并获取 MySQL 表中的自增主键。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • Spring Boot 中配置全局文件上传路径并实现文件上传功能
    本文介绍如何在 Spring Boot 项目中配置全局文件上传路径,并通过读取配置项实现文件上传功能。通过这种方式,可以更好地管理和维护文件路径。 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • 单片微机原理P3:80C51外部拓展系统
      外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。0.IO接口电路概念与存 ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • com.hazelcast.config.MapConfig.isStatisticsEnabled()方法的使用及代码示例 ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 2022年7月20日:关键数据与市场动态分析
    2022年7月20日,本文对当日的关键数据和市场动态进行了深入分析。主要内容包括:1. 关键数据的解读与趋势分析;2. 市场动态的变化及其对投资策略的影响;3. 相关经济指标的评估。通过这些分析,帮助读者更好地理解当前市场环境,为决策提供参考。 ... [详细]
  • 本文详细探讨了在ASP.NET环境中通过加密数据库连接字符串来提升数据安全性的方法。加密技术不仅能够有效防止敏感信息泄露,还能增强应用程序的整体安全性。文中介绍了多种加密手段及其实施步骤,帮助开发者在日常开发过程中更好地保护数据库连接信息,确保数据传输的安全可靠。 ... [详细]
  • 本文探讨了基于点集估算图像区域的Alpha形状算法在Python中的应用。通过改进传统的Delaunay三角剖分方法,该算法能够生成更加灵活和精确的形状轮廓,避免了单纯使用Delaunay三角剖分时可能出现的过大三角形问题。这种“模糊Delaunay三角剖分”技术不仅提高了形状的准确性,还增强了对复杂图像区域的适应能力。 ... [详细]
author-avatar
Caroline19921009
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有