位置:首页 > Swift > Swift中的param pack:深入解析some与any关键字

Swift中的param pack:深入解析some与any关键字

时间:2026-08-27  |  作者:宇宙开黑者  |  阅读:0

目录

  1. 前言介绍
  2. some
  3. any
  4. param pack
  5. 一个应用实例
some 对应的技术说明图
some概括some的核心概念、关键要点与实践提示。
前言介绍 对应的技术说明图
前言介绍概括前言介绍的核心概念、关键要点与实践提示。

前言

Swift语言在类型系统演进中引入了some和any两个关键关键字,旨在更灵活地处理协议约束。some关键字自Swift 5.1起用于创建不透明类型,编译器将其视为具体的唯一隐式类型,行为等同于泛型约束,广泛应用于函数参数、返回值及变量定义中。相比之下,any关键字于Swift 5.6引入,它将类型包装为存在性容器,允许对符合协议的多种类型进行重复赋值,从而在保持类型安全的同时提供了更高的灵活性。

Swift中的param pack:深入解析some与any关键字 的核心流程信息图
Swift中的param pack:深入解析用简体中文信息图概括Swift中的param pack:深入解析的核心流程、关键规则与实践要点。

前言介绍

Swift中已经有some和any两个关键字用于配合协议使用,来约束使用者的类型必须符合协议

some

some关键字是在Swift5.1中引入,用于配合协议使用,创建不透明类型。在编译器看来,传入的参数依然是具体的类型,编译器使用了一个唯一的隐式类型接收这个类型,只不过编译器保证这个类型是遵循了这个协议的。它和使用泛型约束语法没任何区别

所以以下三种代码是等价的

// 使用简短泛型语法,约束T遵守协议
func wash<T: Vehicle>(_ vehicle: T) {}

// 使用完整泛型语法,约束T遵守协议
func wash<T>(_ vehicle: T) where T: Vehicle {}

// 使用some关键字,约束 匿名的不透明类型 遵守协议
// 因为这个类型在编译器看来和普通泛型类型的实参没任何区别。所以叫不透明类型
func wash(_ vehicle: some Vehicle)  {}

some关键字可以用于函数参数、变量类型、类型修饰、函数返回值等

// 函数参数使用some
func funcUseSome(_ v: some Vehicle) {}
// 变量使用some
let varUseSome: some Vehicle = Car()
// 函数返回值类型使用some
func createSomeVehicle() -> some Vehicle {
    return Car()
}
// 数组使用some
let arrUseSome: [some Vehicle] = []

不透明类型表示的隐式类型每次都是唯一的。下面的代码,一旦car变量就是一个隐式的不透明类型。

即使第二行代码又给car赋值了Car实例,这个Car类型也和上面生成的不透明类型不一样,会报错

var car: some Vehicle = Car()

// Cannot assign value of type 'Car' to type 'some Vehicle'
car = Car()

any

any是Swift5.6引入的,也是配合协议使用。它和some不同的是,它会将类型包装成existantial container。并且针对值类型和引用类型分别包装成不同容器类型

let myCar: any Vehicle = Car()
func wash(_ vehicle: any Vehicle)  {}

any不会和some一样生成不透明的唯一类型,它最终就是Container类型,可以重复的赋值,只要符合协议就行

 var myCar: any Vehicle = Car()
 // 这里还可以继续赋值
 myCar = Bus()
 myCar = Car()
 
// 函数的if分支里,只要是符合协议的类型,都可以返回
func createAnyVehicle(isPublicTransport: Bool) -> any Vehicle {
    if isPublicTransport {
        return Bus()
    } else {
        return Car()
    }
}

param pack

some 可以在保证在编译期就知道具体的类型,效率高。但它无法在集合中存放不同的符合协议的类型

any 把所有类型包装成existential container,极大的提高了灵活性,但同时也降低了效率

param pack 在Swift5.9引入,可以看作是对some的增强。这样我们在写接收不确定数量的泛型的函数时,就不用写多个重载函数了,用一个就可以搞定

没有param pack之前, 我们如果要支持元组的比较,要写N多个重载函数

一个应用实例

假设存在一个协议,能够生成任意类型的值。我们拥有多个可能产出数值或引发错误的生产者,目标是收集所有成功生成的值,并自动过滤掉错误情况。借助 param pack 特性,只需编写一个函数即可处理。在 Swift 6.0 中,param pack 支持 for in 循环,使得代码结构更加简洁直观。使用时,只需按照特定语法调用即可实现批量处理,极大简化了代码逻辑。

参考资料

  1. 参数包param pack
  2. 关于some和any
  3. Swift中 Parameter Pack的妙用
func == (lhs: (), rhs: ()) -> Bool

func == <A, B>(lhs: (A, B), rhs: (A, B)) -> Bool where A: Equatable, B: Equatable

func == <A, B, C>(lhs: (A, B, C), rhs: (A, B, C)) -> Bool where A: Equatable, B: Equatable, C: Equatable

// and so on, up to 6-element tuples
// 使用 each Element引入不同的泛型形参
func == Element: Equatable>(lhs: (repeat each Element), 
                                  rhs: (repeat each Element)) -> Bool {
  // 使用repeat each Element重复不同数量的泛型形参
  // 编译器会保证lhs和rhs中泛型形参的数量是相等的
  for (left, right) in repeat (each lhs, each rhs) {
    guard left == right else { return false }
  }
  return true
}
protocol ValueProducer {
  associatedtype Value: Codable
  func evaluate() -> Value
}
func evaluateAllV: ValueProducer, each E: Error>(result: repeat ResultV, each E>) -> [any Codable] {
  var evaluated: [any Codable] = []
  for case .success(let valueProducer) in repeat each result {
    evaluated.append(valueProducer.evaluate())
  }

  return evaluated
}
// 产生整数类型的值
struct IntProducer: ValueProducer {
  let contained: Int
  init(_ contained: Int) {
    self.contained = contained
  }

  func evaluate() -> Int {
    return self.contained
  }
}
// 产生bool类型的值
struct BoolProducer: ValueProducer {
  let contained: Bool
  init(_ contained: Bool) {
    self.contained = contained
  }

  func evaluate() -> Bool {
    return self.contained
  }
}

struct SomeError: Error {}

print(evaluateAll(result:
Result<SomeValueProducer,SomeError>.success(SomeValueProducer(5)),
Result<SomeValueProducer, SomeError>.failure(SomeError()),
Result<BoolProducer, SomeError>.success(BoolProducer(true))))

// [5, true]

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多