6

If I have a protocol that has an optional property, and a class that needs to conform to the protocol which has the same property already, but as a non-optional property, how do I make the class conform to the protocol.

protocol MyProtocol {
    var a: String? { get set }
}

class MyClass {
    var a: String
}

extension MyClass: MyProtocol {
    // What do I put here to make the class conform
}
1
  • In some sense, when reading a, MyClass satisfies a stronger postcondition than the protocol requires. Except if a is required writable then MyClass fails, since it also strengthens the precondition - the protocol requires the optionality. But if the protocol stated a as get only, then is it true that a non-optional implementation of a could indeed conform? (Tested it doesn't) Commented Aug 2, 2018 at 15:44

2 Answers 2

6

Unfortunately, you can't redeclare the same variable in MyClass with a different type.

What Dennis suggests will work, but if you want to keep your variable in MyClass non-Optional, then you could use a computed property to wrap around your stored variable:

protocol MyProtocol {
    var a: String? { get set }
}

class MyClass {
    // Must use a different identifier than 'a'
    // Otherwise, "Invalid redeclaration of 'a'" error
    var b: String
}

extension MyClass: MyProtocol {
    var a: String? {
        get {
            return b
        }
        set {
            if let newValue = newValue {
                b = newValue
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Ronald. This is what I was trying to do, I was just hoping that there was a different way so that I didn't have to have a different name for the variable in my class than in the protocol to use a computed property.
No problem. It may help to consider why having the same identifier won't work: if a can either be a String or a String?, the compiler won't be able to infer the correct type of a whenever it is referenced. This breaks type-safety and makes it more difficult to reason about your code.
Yeah, it makes sense to me. I just was hoping that there was a language feature that I wasn't aware of that got around this. Thanks again.
@RonaldMartin it makes sense why it can't be non-optional, but it seems like it should be able to be a force-unwrapped optional— since the underlying type is optional, but just with a runtime check for non-optionality. Unfortunately this doesn't seem to be allowed…
0

You just have to make the property of the class optional as well in order to conform to the protocol, as follows:

protocol MyProtocol {
    var a: String? { get set }
}

class MyClass {
    var a: String? // Added '?'
}

extension MyClass: MyProtocol {
    // Nothing needed here to conform
}

1 Comment

That's a terrible solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.