Swift Generics: getting rid of the Void parameter “()”
Migrating Swift code from one version to the next can will always be a part of an iOS developer life, and with every iteration, there are always new rules to follow. One rule, in particular, I would like to talk about is this:
In Swift 4, an enum case with a
Void
associated value is no longer equivalent to an enum case with an empty list of associated values.
This means that enumcase foo:
is not the same as case foo(Void)
. This would mean that during initialization you have to explicitly pass a value of type Void.
Void literally means “a completely empty space”, so why should you have to pass nothing in the form of “()”.
Here’s an example of an enum with a Void associated type.
Now instantiating a variable for this on Swift would look like this
let sample: FooBar = .foo()
But then on Swift 4 since we have to pass Void the code now transforms into this
let sample: FooBar = .foo(())
I don’t know about you but the code above looks ugly for me. A way to solve this is to create extension methods or variables which would look like this:
Your code can now again be used like before.
let sampleFoo: FooBar = .foolet sampleBar: FooBar = .bar()
Now how can this be done if you’re using Generics? A good example here would be the Result type.
Again thanks to the amazing type system of Swift we can create a special extension for when the type of Value is Void, with the usage of the where keyword.
That’s it, now you don’t have to write this code (())
.