可以在Swift中禁用一些代码行吗?

时间:2015-07-06 09:04:39

标签: swift macros swift2

我试图通过使用宏来使代码与Swift 1.2和2.0兼容,而无需创建新的分支。

您在自定义Swift编译器标志中定义的Swift中的宏不允许您像Obj-C一样自由地检查条件。

例如,在函数声明中,如果它喜欢Obj-C。我可以做这样的事情。

class ThisIsAClass
{
    #if SWIFT_TWO_POINT_O
       func foo(bar bar: String)
    #else
       func foo(#bar: String)
    #endif
       {
          // Do some common code
          // ...
          // ...

          #if SWIFT_TWO_POINT_O
             print("Do 2.0 things")
          #else
             print("Do 1.2 things")
          #endif
       }
}

函数内的宏条件检查很好。 但是检查声明函数的条件将失败。

有没有办法可以实现这样的目标。

或者在Swift 1.2和2.0分支之间分开是唯一的方法。

1 个答案:

答案 0 :(得分:3)

是的,您可以定义编译器标志并检查它们以有条件地编译部分源as noted in the docs

然而,有一个重要的警告(强调增加):

  

与C预处理器中的条件编译语句相比,Swift 中的条件编译语句必须完全包含自包含且语法有效的代码块。这是因为所有Swift代码都经过语法检查,即使它没有被编译。

所以你做不到:

#if SWIFT_ONE
func foo(/* swift 1 params */)
#else
func foo(/* swift 2 params */)
#endif
{
    // ... function body ...
}

...因为func foo(params)不是语法上完整的元素。 (一个语法上完整的函数声明包括函数体。)同样地,例如,尝试#if围绕类声明而不是其内容等。

那你可以做什么呢?

  • 在这种特殊情况下,func foo(bar bar: String)是完全有效的Swift 1.x语法。 #只是它的简写......所以只需使用简写,你就不必担心语言版本的差异。 (不过,请随时在Twitter上发布#foo和#bar。)

  • 更一般地说,您可以拥有多个单独的功能并发送给它们:

    func foo() {
        #if SWIFT_ONE
        fooForSwift1()
        #else
        fooForSwift2()
        #endif
    }
    
  • 或者对于类或其他类型,您可以使用类型别名:

    class Foo1 { /* ... */ }
    class Foo2 { /* ... */ }
    #if SWIFT_ONE
    typealias Foo = Foo1
    #else
    typealias Foo = Foo2
    #endif