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

I'm trying to make my code compile to both Swift 1.2 and 2.0 without creating a new branch using a macro.

The Swift macro that you defined in the Swift Compiler custom flags does not allow you to validate conditions as freely as Obj-C.

For example, in a function declaration if it looks like Obj-C. I can do something like this.

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
       }
}

      

Checking macros in a function is fine. But the status check for the function declaration will fail.

Is there a way to achieve something like this.

Or splitting between Swift 1.2 and 2.0 branches is the only way.

+3


source to share


1 answer


Yes, you can define compiler flags and check them to conditionally compile parts of your source as stated in the docs .

However, there is an important caveat (emphasis added):

Unlike conditional 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 if it is not compiled.

So what you cannot do:



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

      

... because it is func foo(params)

not a syntactically complete element. (A syntactically complete function declaration includes the body of the function.) Same as, say, trying #if

around a class declaration but not its content, etc.

So what can you do instead?

  • in this particular case, func foo(bar bar: String)

    is absolutely valid Swift 1.x syntax. #

    was just a shorthand for it ... so just use longhand and you don't have to worry about language version differences. (Feel free to post about #foo and #bar on Twitter.)

  • More generally, you can have several separate functions and send 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
    
          

+3


source







All Articles