I’m trying to create a protocol for types that are Lerp-able (linear-interpolatable). I’m declaring it similarly to how Equatable
is defined:
protocol Lerpable {
func lerp(from: Self, to: Self, alpha: Double) -> Self
}
Unfortunately, when I try to implement Lerpable
for Double
:
func lerp(from: Double, to: Double, alpha: Double) -> Double {
return from + alpha * (to - from)
}
extension Double: Lerpable {}
I get an error: Type 'Double' does not conform to protocol 'Lerpable'
.
I assumed this would be pretty straightforward, but maybe I just don’t understand how Equatable works. Or is it a special case in Swift? Any thoughts?
UPDATE: The correct answer is below, and here’s the final version of the code, for others’ reference:
protocol Lerpable {
func lerp(to: Self, alpha: Double) -> Self
}
extension Double: Lerpable {
func lerp(to: Double, alpha: Double) -> Double {
return self + alpha * (to - self)
}
}
func lerp<T: Lerpable>(from: T, to: T, alpha: Double) -> T {
return from.lerp(to, alpha: alpha)
}
I added the global lerp
function so I could still refer to it as
lerp(foo, bar, alpha: 0.5)
rather than
foo.lerp(bar, alpha: 0.5)
To fix your problem you need to put the lerp
function inside your extension
, like so:
extension Double: Lerpable {
func lerp(from: Double, to: Double, alpha: Double) -> Double {
return from + alpha * (to - from)
}
}
If you have a look at the Equatable
protocol
:
protocol Equatable {
func == (lhs: Self, rhs: Self) -> Bool
}
The reason you declare its method (==
specifically) outside your type extension
is because Equatable
wants you to overload an operator and operators must be declared at global scope. Here's an example to clarify:
protocol MyProtocol {
func *** (lhs: Self, rhs: Self) -> Self
}
Now to make Int
adopt the protocol:
extension Int : MyProtocol {}
infix operator *** {}
func *** (lhs: Int, rhs: Int) -> Int {
return lhs * rhs
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With