Search code examples
swiftswift-protocols

Protocol conformance


I have protocols:

public protocol DCUUID {
    init(string: String)
    var uuidString: String { get }
}

public protocol DCPipe {
    var uuid: DCUUID { get }
}

Then I try to use it:

extension CBUUID: DCUUID {}

extension CBAttribute: DCPipe {}

The compiler says that CBAttribute does not conform DCPipe.

CBAttribute has property

var uuid: CBUUID { get }

CBUUID is DCUUID. So CBAttribute has property uuid that return DCUUID.

What is wrong?


Solution

  • If you declare the requirement to be a protocol, it expects a property that can be any implementation of that protocol. The following will work, for example:

    struct CBAttribute
    {
        var cbId: CBUUID
    }
    
    extension CBAttribute: DCPipe {
        var uuid: any DCUUID { cbId }
    }
    

    You could argue that, because the requirement is get only, the way you have done it shouldn't be an issue, but it is.

    It's probably better practice, however, to use an associated type in the protocol

    public protocol DCUUID {
        init(string: String)
        var uuidString: String { get }
    }
    
    public protocol DCPipe {
        associatedtype IDType: DCUUID
        var uuid: IDType { get }
    }
    
    struct CBUUID
    {
        var uuidString: String
    }
    
    extension CBUUID: DCUUID
    {
        init(string: String) 
        {
            self.init(uuidString: string)
        }
    }
    
    struct CBAttribute
    {
        var uuid: CBUUID
    }
    
    extension CBAttribute: DCPipe {}
    

    This way, you don't need the weird computed property.