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.
source to share
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
source to share