Member-only story
Top 7 Subtle Swift Features
Enums as namespaces, dynamically callable, and more

1. Keyword indirect
It’s used with enums only. As you know, enums are value type and stored on the stack. Therefore, the compiler needs to know how much memory each enum takes.
As only one option is possible at any moment, the enum occupies the memory of the largest case plus some operational information.
// Just a general enum, nothing fancy
enum Foo {
case bizz(String)
case fizz(Int)
}
But what if we make enum dependant on itself?
// Infinite size??
enum Foo {
case bizz(Foo)
case fizz
}
This definition generates a compiler error.
Recursive enum
Foo
is not markedindirect
The error makes sense: the compiler can’t calculate Foo
size as it tends to infinity. Here comes the indirect
keyword.
// Oh, fine
enum Foo {
indirect case bizz(Foo)
case fizz
}
- Simple: it modifies the enum memory structure to solve the recursion problem.
- Detailed:
.bizz(Foo)
is no longer stored inline in memory. Actually, with theindirect
modifier data is now stored behind a pointer (indirectly).
Problem solved! Also, we can modify the whole enum as indirect
// Every case is indirect now
indirect enum Foo {
case bizz(Foo?)
case fizz(Foo?)
}
2. Attribute @autoclosure
Swift’s @autoclosure
attribute enables you to define an argument that automatically gets wrapped in a closure. It’s mostly used to defer the execution of an expression to when it’s actually needed.
Then, calculate can be called like this: