Indirect Enums on practice

Daniil Vorobyev
3 min readJan 20, 2020

As we know, Enumeration (Enum) defines a common type for a group of related values and enables you to work with those values in a type-safe way within your code. Sometimes we also need to have associated values — I suppose most of iOS Developers have ever written something like this:

Associated value

But what happens if we try to specify in the associated value our enum itself?

Let’s try to write:

Ooops… recursive enum error

FAIL. Compiler shows error: “Recursive enum ‘%EnumName’ is not marked ‘indirect’” . Now we going to figure out what the error is it and how to fix it while preserving our functionality

As I said earlier, enums are value type, which due to the specifics of Apple memory management must be determined at compile time. In other words, we must know exactly how many memory cells we need to allocate for each instance stored on stack. So, when we determine inside one value type object the same value type object, we create a kind of recursion where it is impossible to understand how much memory is needed for such an object. In fact, another problem is deduced from this: We can’t determine property of type A inside struct A.

Error described above

But back to our problem and try to figure out how swift works with associated values enums:

  • For a Swift enum, enum object will only have one case assigned to itself (since it can’t assigned two values at the same time)
  • Then compiler checks which case of the enum will occupy the maximum memory.
  • Now the instance of enum will have the required memory plus some static memory for current state tracking.

So how to store recursive associated values?

Solve the problem!

Special word — indirect — solves the error.

Indirect modify the way Swift stores enum so they can grow to any size. We also can apply indirect only to some cases but not to the whole enum:

It’s also possible

Do this when not all of enum’s cases referring recursively itself.

Let’s figuring out what happens when we indicate this declaration modifier. The explanation is easy enough: Indirect instructs the compiler to store the enum’s data behind a pointer. Another word, a static memory size is allocated for storing the refference on the stack, but the content (as I guess) stored on the heap. Thus after these optimizations, no need to make the instance of Enum big enough to hold the whole data.

I hope this article has been helpful to you!

https://www.tothenew.com/blog/recursive-enumerations-in-swift/ — Excellent article which i used in my own

--

--