Protocol method requirement – allow method parameter to be replaced/overriden by conforming type?

I have a protocol, Device, which contains the required method makeACopy(device: Device) -> Device. When a struct conforms to Device, it should specify itself in place of Device.

Now, I want to make my Phone struct conform to Device. However, when I conform to the makeACopy(device: Device) -> Device requirement with makeACopy(device: Phone) -> Phone, I get this error:

Type ‘Phone’ does not conform to protocol ‘Device’

Here’s my code:

protocol Device {
    var name: String { get set }
    func makeACopy(device: Device) -> Device
}

struct Phone: Device { /// Error: Type 'Phone' does not conform to protocol 'Device'
    var name = "My Phone"
    func makeACopy(device: Phone) -> Phone { /// my attempt to conform to `Device`'s method requirement
        return Phone(name: self.name)
    }
}

Since Phone conforms to Device, I thought my makeACopy(device: Phone) -> Phone method would satisfy the protocol. But apparently not.

How can I make Device‘s func makeACopy(device: Device) -> Device requirement accept protocol-conforming substitutes for the parameter? For example, replacing device: Device with device: Phone?

>Solution :

It sounds like you’re looking for this, which guarantees that both the input and output are the same type and conform to Device:

protocol Device {
    var name: String { get set }
    func makeACopy(device: Self) -> Self //<-- Note that `Self` is used instead of `Device`
}

Leave a Reply