Home > OS >  How to add default implementation using generic protocol extension?
How to add default implementation using generic protocol extension?

Time:08-15

I want to add default implementation for Int/Float/Double value.

protocol ValueLimit {
    associatedtype T where T: Comparable

    func limit(from minValue: T, to maxValue: T) -> T
}

extension ValueLimit {
    func limit(from minValue: T, to maxValue: T) -> T {
        return Swift.max(Swift.min(self as! Self.T, maxValue), minValue)
    }
}

extension Int: ValueLimit {
    typealias T = Int
}

extension Float: ValueLimit {
    typealias T = Float
}

extension Double: ValueLimit {
    typealias T = Double
}

I belive there is a better way, which can simply use empty extension extension Int: ValueLimit {} to do this, without typealias T = Int, but I don't know how to do this.

CodePudding user response:

There's no need for an associated type, you can simply use Self in your limit declaration. You can also declare that conforming types need to conform to Comparable as well in the protocol declaration.

Self refers to the current type, so when using it in protocol methods, it refers to the conforming type. This is how standard library protocols such as Equatable and Comparable are implemented as well.

protocol ValueLimit: Comparable {
    func limit(from minValue: Self, to maxValue: Self) -> Self
}

extension ValueLimit {
    func limit(from minValue: Self, to maxValue: Self) -> Self {
        Swift.max(Swift.min(self, maxValue), minValue)
    }
}

extension Int: ValueLimit {}

extension Float: ValueLimit {}

extension Double: ValueLimit {}

CodePudding user response:

Maybe this would be simpler.

extension Comparable {
    func limit(from minValue: Self, to maxValue: Self) -> Self {
        return Swift.max(Swift.min(self, maxValue), minValue)
    }
}
  • Related