在Swift中使用编译器变量

在Swift中使用编译器变量,swift,compiler-flags,Swift,Compiler Flags,在Objective-C中,我在Build Settings->代码中使用的其他C标志中设置了一组编译器标志。例如: Flag=>-DPortNumber=1 在代码中,我可以通过@(端口号) 这在Swift中不起作用,我找不到答案。C编译器的-D标志定义了一个预处理器宏。Swift中没有预处理器宏。因此,如果您希望做以下事情: // compile with -DPORT_NUMBER 31337 var port = PORT_NUMBER // error 。。。你不能。Swift

在Objective-C中,我在Build Settings->代码中使用的其他C标志中设置了一组编译器标志。例如:

Flag=>-DPortNumber=1

在代码中,我可以通过
@(端口号)


这在Swift中不起作用,我找不到答案。

C编译器的
-D
标志定义了一个预处理器宏。Swift中没有预处理器宏。因此,如果您希望做以下事情:

// compile with -DPORT_NUMBER 31337
var port = PORT_NUMBER    // error
。。。你不能。Swift是为源代码在编译前语法完整而设计的。如果您可以在构建时切换它的块,那么您将破坏工具链帮助验证代码正确性的能力。(部分原因是C中的预处理器宏是文本替换:您可以使用它们重写语言的任何部分,而不仅仅是填充变量的值。)

Swift编译器确实有一个
-D
标志,但它的使用更为有限:您只能将其用于。因此,如果你想做以下事情,你会很酷:

// compile with -DUSE_STAGING_SERVER
#if USE_STAGING_SERVER
var port = 31337
#else
var port = 80
#endif
请注意,与C不同,
#if
块中的所有内容都需要在语法上完整。(例如,不能仅将
func
的声明行放入
#if
块中,并将函数体保留在条件之外。)


当然,如果您希望在编译时设置一个配置值并在代码中使用,这对您没有帮助。为此,我推荐其他方法。Xcode仍然可以在资源文件中进行文本替换,如属性列表。(请注意,应用程序附带的Info.plist中充满了诸如
$(TARGET_NAME)
之类的内容。)因此,您可以在应用程序中包含一个捆绑资源,其内容在编译时根据项目设置填充,然后从中读取您的端口号。

那么,是否可以让用户定义的值通过类似于“MY_value”的CI传递,该CI将在.plist中引用,并且可以从Swift中读取?对-如果您在plist中有类似于
someKey=$(MY_value)
(好,但在XML中),则构建系统将填充MY_值。(查看模板项目附带的Info.plist,其中一些东西,如bundle name就是这样定义的。)然后从plist加载值的Swift代码将获得构建系统定义的值。