Swift等价于#define,用于检索变量参数列表
所以我在C中有一个函数Swift等价于#define,用于检索变量参数列表,swift,macros,Swift,Macros,所以我在C中有一个函数 #define PRINTF(format) { va_list list; va_start(list, format); vprintf(format, list);} void foo(const char* format, ...) { PRINTF(format) } 我想知道,如果我要使上述代码的Swift等效,我将如何表示。。。作为?我知道如何使用变量参数的唯一方法是使用CVarArgType,或者使用参数数组 然而,由于这个C代码段使用了宏,我发
#define PRINTF(format) { va_list list; va_start(list, format); vprintf(format, list);}
void foo(const char* format, ...) {
PRINTF(format)
}
我想知道,如果我要使上述代码的Swift等效,我将如何表示。。。作为?我知道如何使用变量参数的唯一方法是使用CVarArgType,或者使用参数数组
然而,由于这个C代码段使用了宏,我发现在不改变我所做的函数的参数而不是宏的情况下,很难将这段代码移植到Swift。对于我将如何着手做这样的事情,我能得到一些见解或帮助吗
我需要帮助以Swift编写“定义宏等效函数”,但我在生成等效于va_列表、va_开始调用时遇到了麻烦。好吧,我最初的答案绝对让事情过于复杂了 我们确实需要使用
字符串作为格式,使用CVarArgType…
作为参数列表(在函数中被视为[CVarArgType]
)。我尝试使用Objective-C的NSString
使它复杂化。如果我们坚持使用Swift的字符串
,它实际上有一个初始值设定项,它接受我们传递的参数
用Swift编写此函数的最简单方法如下所示:
func foo(format: String, args: CVarArgType...) {
println(String(format: format, arguments: args))
}
func foo(format: String, args: CVarArgType...) {
func buildLogString(argList: CVaListPointer) -> String {
return NSString(format: format, arguments: argList) as String
}
println(withVaList(args, buildLogString))
}
据我所知,Swift不允许使用#define
宏。但是,我们可以将该C宏转换为常规Swift函数
func foo(format: String, args: CVarArgType...) {
println(NSString(format: format, arguments: getVaList(args)))
}
CVarArgType
是一种Swift协议,它接受我们通常传递到字符串中的类型,用于格式化字符串
…
使函数接受最后一个参数的任意数量的参数。在函数中,它将具有类型[CVarArgType]
(一个数组)
同时,NSString
的初始值设定项(类似地,NSLog
和其他类似点)正在寻找CVaListPointer
作为最后一个参数,因此我们可以使用Swift的内置函数,getVaList
,它将[CVarArgType]
转换为CVaListPointer
此函数可以这样调用:
foo("%@, %@... %i", "hello", "world", 123)
将打印:
你好,世界。。。123
正如@AirspeedVelocity所指出的,一般建议使用with valist
而不是getVaList
。我们可以这样做:
func foo(format: String, args: CVarArgType...) {
println(String(format: format, arguments: args))
}
func foo(format: String, args: CVarArgType...) {
func buildLogString(argList: CVaListPointer) -> String {
return NSString(format: format, arguments: argList) as String
}
println(withVaList(args, buildLogString))
}
对于这个特定示例以外的应用程序,需要注意的是,我们可以使用…
接受任何类型的参数列表,并且在函数中,我们可以得到该类型的数组
例如:
func bar(myVariadicListOfStuff: MyStuffClass...) {
// myVariadicListOfStuff is a [MyStuffClass]
for thing in myVariadicListOfStuff {
// this is a MyStuffClass
}
}
苹果认为(我也倾向于同意)宏的定义使得调试更加困难,因此不允许在Swift中使用宏。尽管如此,在Swift中可能仍然有一种方法可以接受不同数量的论点。现在还不清楚你到底在问什么。您想知道如何调用接受va_列表的C函数吗?(在这种情况下:withVaList([1,1.2]){vprintf(“一个int:%d\na float:%f”,$0)}
将起作用)。或者你是想用Swift申报吗?或者一般来说,如何在Swift中定义宏?基本上,我需要帮助将上述代码转换为Swift等效代码。由于Swift不允许使用宏,我认为我需要为它编写一个函数。我不知道如何在Swift中复制上述宏的行为,特别是va_列表,va_开始调用。啊,好吧,看起来你有一个,也就是说,你想知道如何调用C var arg函数,但你问了关于\define
宏的问题。但是@nhgrif的答案符合您的需要:)注意,正如上面的文档注释所说,“警告::最好避免使用with valist
”@AirspeedVelocity我更新了答案。。。而且觉得自己是个白痴,因为它太复杂了,呵呵。看看答案的最上面部分。。。