Swift: Putting Your Generics in a Box

One of my favorite functional patterns that I now use in Swift is the Result enum  for error handling:

enum Result<T> {
    case Success(T)
    case Failure(NSError)
}

I won’t go into much detail on this, but I highly recommend reading Alexandros Salazar’s great explanation of why this is magic. Also make sure to check out Scott Wlaschin’s Railway oriented programming for the exciting possibilities (video version here).

Now back to the original point of my post. Try putting the above Result enum into the Playground or your project code (that’s what I did immediately after reading about it…). Hint: It will not work! From my understanding, this is because the compiler doesn’t know how much memory to allocate for the generic type in the enum.

Hopefully this will be fixed in future versions of Swift, but for now the workout is to “Box” your generic type – in other words, wrap it in a class.

final class Box<T> {
    let value: T
    
    init(value: T) {
        self.value = value
    }
}

enum Result<T> {
    case Success(Box<T>)
    case Failure(NSError)
}

So now, you can use the result enum as follows:

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let result = Result.Success(Box(value: "hello"))
        
        handleResult(result)
    }
    
    func handleResult(result: Result<String>) {
        switch result {
        case .Success(let box):
            println(box.value)
        case .Failure(let error):
            println(error.description)
        }
    }
}

This type of Box pattern is useful to know in general, especially when working with generics.

For better understanding of actual Result pattern code (vs just theory) in Swift, make sure to check out the Result library on Github here.

Happy to hear additional thoughts and explanations about the Result enum and the Box pattern in the comments!

Enjoy the article? Join over 20,000+ Swift developers and enthusiasts who get my weekly updates.