Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift等价于#define,用于检索变量参数列表_Swift_Macros - Fatal编程技术网

Swift等价于#define,用于检索变量参数列表

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代码段使用了宏,我发

所以我在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我更新了答案。。。而且觉得自己是个白痴,因为它太复杂了,呵呵。看看答案的最上面部分。。。