在 Swift 5.4 允许多个可变参数在方法、下标、初始化方法
Variadic Parameter Definify
可变参数(variadic parameter)可以接受零或多个值,通过在变量类型后面加入 (...) 的方式来定义
Before & After
在 Swift 5.4 之前,只允许一个可变参数在参数列表中,每一个可变参数均需要添加标签。修改后允许多个可变参数,并且只需要限制在可变参数后面的参数有标签
Motivation
在 Swift 5.4 之前
func assertArgs(
_ args: String...,
parseTo driverKind: DriverKind,
leaving remainingArgs: ArraySlice<String>,
file: StaticString = #file, line: UInt = #line) { }
/// 这里 leaving 用的是数组 [], 且声明为 ArraySlice<String>,受只有一个可变参数的限制
// try assertArgs("swift", "-foo", "-bar", parseTo: .interactive, leaving: ["-foo", "-bar"])
如果参数列表允许有多个可变参数,代码将会更加简洁
func assertArgs(
_ args: String...,
parseTo driverKind: DriverKind,
leaving remainingArgs: String...,
file: StaticString = #file, line: UInt = #line) { }
// try assertArgs("swift", "-foo", "-bar", parseTo: .interactive, leaving: "-foo", "-bar")
Detailed Design
Section 0 : 在 twoVarargs
中,a 和 b 都是 Int 型,需要知道 a 可变参数列表,在什么时候结束
func twoVarargs(_ a: Int..., b: Int...) {}
/// 可变参数默认值是 [], 所以可以不传
func test_twoVarargs() {
/// b 参数省略,默认为 []
twoVarargs(1, 2, 3)
/// a 参数省略,默认为 []
twoVarargs(b: 4, 5, 6)
/// a 和 b 参数均省略,默认为 []
twoVarargs()
}
Section 1 : 两个可变参数被一个其他参数分割,且后面一个可变参数省略标签
func splitVarargs(a: Int..., b: Int, _ c: Int...) {}
func test_splitVarargs() {
/// a = [1, 2, 3], b = 4, c = [5, 6]
splitVarargs(a: 1, 2, 3, b: 4, 5, 6)
/// a = [], b = 4, c = []
splitVarargs(b: 4)
}
Section 2 : 两个可变参数被一个其他参数分割,且两个可变参数均省略标签
func varargsSplitByDefaultParam(_ a: Int..., b: Int = 42, _ c: Int...) {}
func test_varargsSplitByDefaultParam() {
/// a = [1, 2, 3], b = 4, c = [5, 6, 7]
varargsSplitByDefaultParam(1, 2, 3, b: 4, 5 ,6, 7)
/// a = [], b = 4, c = [6, 7]
varargsSplitByDefaultParam(b: 4, 5, 6, 7)
/// a = [1, 2, 3], b = 42, c = []
varargsSplitByDefaultParam(1, 2, 3)
}
目前像这种不同类型的也还不能自动识别,需要手动添加标签进行隔离
/// 编译报错
// func varargs(a: Int..., _ b: String) {}
下标 : 现在下标方法默认需要指定标签
subscript(a: Int..., b b: String) -> Int { 0 }
func test_subscript() {
let _ = self[1, b: "12"]
}
/// 以下均编译报错
// subscript(a: Int..., b: String) -> Int { 0 }
// subscript(a: Int..., c: String = "Hello, World!") -> Bool { false }
网友评论