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

3
我希望您能够使用宏的方式,让我的代码同时支持Swift 1.2和2.0的编译,且不需要创建新的分支。
在Swift中,通过自定义Swift编译标记来定义宏,并不能像Objective-C那样自由地检查条件。
例如,在函数声明中,如果使用Objective-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分支是唯一的方法。


希望这可以帮到你:https://dev59.com/xWAf5IYBdhLWcg3w9Wiu#24112024 - Ashish Kakkad
函数内的宏条件检查是可以的。 但我想要做的是跨越函数之间的检查。 无论如何,谢谢。 - myLifeasdog
3
你不能针对语言特性这样做,只能针对框架特性这样做。如果你需要让你的源代码兼容Swift 1.2和2.0版本,那么拥有两个分支确实是正确的方法。 - Eric Aya
1个回答

3

是的,你可以定义编译器标志并检查它们以有条件地编译源代码的部分,如文档中所述

然而,这里有一个重要的注意事项(已经强调):

与 C 预处理器中的条件编译语句不同,Swift 中的条件编译语句必须完全包围自包含和语法有效的代码块。这是因为所有的 Swift 代码都会进行语法检查,即使它没有被编译。

因此,你不能这样做:

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

因为func foo(params)不是一个语法上完整的元素。(一个语法上完整的函数声明包括函数体。)同样的,尝试在类声明周围添加#if但不包括其内容也是一样的。

那么你可以做什么呢?

  • in this particular case, func foo(bar bar: String) is perfectly valid Swift 1.x syntax. The # was merely a shorthand for it... so just use the longhand and you won't have to worry about language-version differences. (Feel free to post about #foo and #bar on Twitter, though.)

  • more generally, you can have multiple separate functions and dispatch to them:

    func foo() {
        #if SWIFT_ONE
        fooForSwift1()
        #else
        fooForSwift2()
        #endif
    }
    
  • or for classes or other types, you can use type aliases:

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

实际上,函数声明并不是什么问题,但我选择它作为禁用某些代码行的示例,因为我认为这样更清晰。真正困扰我的是Swift 2.0中的新错误处理方式。 但从您提供的链接中,我遵循的Apple文档非常清楚地说明了“这是因为所有Swift代码都经过语法检查,即使在未编译时也是如此”。因此,如果我想要在Swift 1.2编译器上进行编译,我认为我不能使用Swift 2.0语法(try、catch、throws)。 - myLifeasdog
为什么Swift需要这个?这真的很令人沮丧,会导致大量重复代码和奇怪的解决方法。 - odyth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接