在Swift中将变长参数作为数组传递

3

Java 5+ 允许将可变参数作为数组或单独传递。我期望 Swift 也能像 Java 一样允许将可变参数作为数组传递,但目前还没有成功。

下面是一个示例程序,在 playground 中尝试运行。它创建了一个 CVarArg 数组,并将其传递给 String(format:...) 方法。

let printData: [(format: String, param: [CVarArg])] =
    [(format: "This is blank", param: []),
     (format: "This is %@ %@", param: ["Swift", "language"])
   ]

for index in 0...1  {
    let pdata = printData[index]
    print (String(index+1) + " " + String(format: pdata.format, pdata.param))
}

我期望:

1 This is blank
2 This is Swift language

相反,它会打印:

1 This is blank
2 This is (
    Swift,
    language
) (null)

尝试使用CVarArg作为类型:

let printData: [(format: String, param: CVarArg...)]

或者桥接到 CVarArg...:
String(format: pdata.format, pdata.param as CVarArg...)

无论哪种情况,我都会出现编译错误。

是否有一种方法可以更改上述代码的语法,以允许按预期方式解释[CVarArg]。

1个回答

3
我认为你的问题在于元组不支持可变参数。因此,您可以考虑改用列表。
 (format: "This is %@ %@", param: ["Swift", "language"])

一个元组由两个部分组成:一个字符串和一个数组,String(format:,_) 将数组视为单个对象。为解决您的即时问题,请使用String(format:,arguments:)。例如:

for index in 0...1  {
    let pdata = printData[index]
    print (String(index+1) + " " + String(format: pdata.format, arguments: pdata.param))
}

考虑到创建字面量数组的简单性,我对在Swift中使用可变参数的必要性提出了质疑。


String(format:..)是一个不错的字符串处理方法,但并不适用于所有情况。至于可变参数的需求,只是为了方便:无需使用方括号。 - cyanide
如果只是为了节省按键,我们都会用 APL 编程。几年前,在 Swift 进化中有一个关于是否应该删除可变参数的大争论。当时我支持保留它们,但它们并不是必需的。最终,它们被保留下来以实现向后兼容性和与 C API 的接口。我想支持的一个论点是编译器可以检查它们与格式字符串的兼容性。但对于你的用例,这并不起作用。 - JeremyP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接