Search code examples
swiftprotocols

Requiring, for a protocol, that an instance variable conform to a protocol ; rather than have a specific type


As part of a custom Coder, I convert both Float and Double in the exact same way :

static func encode(_ value : Double) -> Data {
    withUnsafeBytes(of: value.bitPattern.bigEndian) { Data($0) }
}

static func encode(_ value : Float) -> Data {
    withUnsafeBytes(of: value.bitPattern.bigEndian) { Data($0) }
}

I thought that instead I could require that value would conform to a protocol, and since the FloatingPoint protocol does not guarantee the presence of bitPattern, I thought I would make my own :

protocol CompatibleFloatingPoint {
    var bitPattern : FixedWidthInteger { get }
}

This, however, gives the following error : Protocol 'FixedWidthInteger' can only be used as a generic constraint because it has Self or associated type requirements

However, I cannot replace FixedWidthInteger with a specific type, as Double.bitPattern is a UInt64 and Float.bitPattern is a UInt32

What is the proper syntax to require that bitPattern conform to the FixedWidthInteger protocol without forcing it to have a specific type ?


Solution

  • What you're looking for is an associated type. This means exactly what you've described (the required type conforms to a protocol rather than being the existential of that protocol):

    protocol CompatibleFloatingPoint {
        associatedtype BitPattern: FixedWidthInteger
        var bitPattern : BitPattern { get }
    }
    
    extension Float: CompatibleFloatingPoint {}
    extension Double: CompatibleFloatingPoint {}
    

    For more details, see Associated Types in the Swift Programming Language.