是否可以禁用 Swift 中的某些代码行?

Is it possible to disable some lines of code in Swift?

我试图通过使用宏使我的代码可以同时使用 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 分支之间分开是唯一的方法。

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

但是,有一个重要的警告(强调):

In contrast with condition compilation statements in the C preprocessor, conditional compilation statements in Swift must completely surround blocks of code that are self-contained and syntactically valid. This is because all Swift code is syntax checked, even when it is not compiled.

所以你不能这样做:

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

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

那么你可以做什么呢?

  • 在这种特殊情况下,func foo(bar bar: String) 是完全有效的 Swift 1.x 语法。 # 只是一个 shorthand 而已……所以只要使用普通写法,您就不必担心语言版本的差异。 (尽管如此,请随时 post 关于 Twitter 上的#foo 和#bar。)

  • 更一般地说,您可以拥有多个单独的函数并分派给它们:

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

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