Swift 5.9 新特性:值和类型参数包

前言

在 Swift5.9 的版本中,经过 Apple 进行一系列的改动,可以允许开发者使用可变泛型参数。

上述改动解决了 Swift 中的一个很重要问题,就是泛型函数需要特定数量的类型参数。虽然这些函数仍然可以接受可变参数,但它们最终仍然必须使用相同的类型。

比如下面的例子,假设我们三个不同的结构体用来代表程序员不同的角色:

arduino 复制代码
struct FrontEndDev {
    var name: String
}

struct BackEndDev {
    var name: String
}

struct FullStackDev {
    var name: String
}

当然,在实际需求中这些结构体会有更多的属性用来实现需求,但此处仅是举例,所以只给结构体一个 name 的属性。

接着我们为每个结构体创建实例:

ini 复制代码
let johnny = FrontEndDev(name: "Johnny Appleseed")
let jess = FrontEndDev(name: "Jessica Appleseed")
let kate = BackEndDev(name: "Kate Bell")
let kevin = BackEndDev(name: "Kevin Bell")

let derek = FullStackDev(name: "Derek Derekson")

然后,当涉及到实际工作时,我们可以使用一个简单的函数将开发人员匹配在一起,如下所示:

swift 复制代码
func pairUp1<T, U>(firstPeople: T..., secondPeople: U...) -> ([(T, U)]) {
    assert(firstPeople.count == secondPeople.count, "You must provide equal numbers of people to pair.")
    var result = [(T, U)]()

    for i in 0..<firstPeople.count {
        result.append((firstPeople[i], secondPeople[i]))
    }

    return result
}

它使用两个可变参数来接收一组第一个人和一组第二个人,然后将它们作为数组返回。我们现在可以使用它来创建一个组程序员,改组需要处理某些前端和后端的工作。

ini 复制代码
let result1 = pairUp1(firstPeople: johnny, jess, secondPeople: kate, kevin)

到目前为止,都是按照 Swift 5.9 之前的版本去写的代码。但有趣的是: Derek 是一名全栈开发人员,因此既可以担任后端开发人员,也可以担任前端开发人员。然而,如果我们尝试使用johnny, derek作为第一个参数,那么 Swift 编译器将会报错。因为它需要第一个人和第二个人的类型是相同的。

我们可以使用 any 关键字来抹除所有的类型信息,从而解决这个问题。但这样就失去了很多可以利用的 Swift 特性,我们可以用参数包来更优雅的解决这个问题。

参数包

乍一开始看到这个语法可能会有点懵,下面先写出完整代码,后面再一点点分解它:

sql 复制代码
func pairUp2<each T, each U>(firstPeople: repeat each T, secondPeople: repeat each U) -> (repeat (first: each T, second: each U)) {
    return (repeat (each firstPeople, each secondPeople))
}

让我们分解成四部分来理解它:

  • <each T, each U> 创建了两个类型参数包, TU
  • repeat each T 是一个包扩展,它将参数包扩展为实际值 - 它相当于 T...,但避免了与 ... 用作运算符造成混淆
  • 返回类型意味着我们要发回配对程序员的元组,TU 各一个
  • return 关键字的作用:它使用包扩展表达式从 T 中获取一个值,从 U 中获取一个值,然后将它们组合在一起形成返回值

需要注意的是,返回类型会自动确保我们的 TU 类型具有相同的形状------它们内部具有相同数量的元素。因此,如果我们试图传入两组不同大小的数据,Swift 会编译报错,而不是像在第一个函数中那样使用assert()

下面是新函数的调用示例:

ini 复制代码
let result2 = pairUp2(firstPeople: johnny, derek, secondPeople: kate, kevin)
相关推荐
Swift社区13 小时前
Apple 新品发布会亮点有哪些 | Swift 周报 issue 61
ios·swiftui·swift
营赢盈英3 天前
OpenAI GPT-3 API error: “You must provide a model parameter“
chatgpt·gpt-3·openai·swift
一只不会编程的猫3 天前
高德地图绘图,点标记,并计算中心点
开发语言·ios·swift
loongloongz4 天前
Swift语言基础教程、Swift练手小项目、Swift知识点实例化学习
开发语言·学习·swift
2401_858120537 天前
深入理解 Swift 中的隐式解包可选类型(Implicitly Unwrapped Optionals)
开发语言·ios·swift
quaer7 天前
QT chart案例
开发语言·qt·swift
安和昂8 天前
【iOS】UIViewController的生命周期
ios·xcode·swift
00圈圈8 天前
Swift 创建扩展(Extension)
ios·swift·extension
2401_858120538 天前
Swift 中的函数:定义、使用与实践指南
开发语言·ssh·swift
quaer9 天前
VS+QT--实现二进制和十进制的转换(含分数部分)
java·开发语言·python·qt·swift