Norway


In Swift Talk 45, we wrote a library for parsing routes. We represented routes as enums, and added a custom initializer to parse routes:

 Route {
    case home
    case users(id: Int)
}

extension Route {
    init?(path: String) {
        if path == "/" {
            self = .home
        } else if path.hasPrefix("/users") {
            self = .users(id: 1)
        } else {
            return nil
        }
    }
}

Of course, this code isn’t complete (see the full public episode for that).

Today, we want to focus on assigning to self inside the initializer. In the initializer of any struct or enum we can treat self as a mutable variable (as if it were declared using inout). This is why we can do the following:

enum Result<A> {
    case success(A)
    case error(Error)
}

extension Result {
    init(_ value: A) {
        self = .success(value)
    }
}

We can even do this in a struct, although it’s easier to just call self.init:

extension UIEdgeInsets {
    init(all value: CGFloat) {
        self = .init(: value, left: value, bottom: value, right: value)
    }
}

We can also use the same technique if we need a little more flexibility than RawRepresentable, or if we want to provide a default value:

enum Method {
    case post
    case get
}

extension Method {
    init() {
      self = .get
    }

    init?(_ value: String) {
        switch value.lowercased() {
        case "post": self = .post
        case "get": self = .get
        default: return nil
        }
    }
}

If you enjoyed this , check out the episode below, or watch Swift Talk 21: Structs and Mutation for more information on how to work with inout.

If you’d like to watch all our episodes, you can subscribe 😉

Enjoy!



Source link
Based Blockchain Network

LEAVE A REPLY

Please enter your comment!
Please enter your name here