CGFloat/Double not interchangeable in protocol implementation?

import UIKit

protocol Foo {
    func bar() -> CGFloat
}

struct Good: Foo {
    func bar() -> CGFloat { 0 }
}

// Compile error: Type 'Bad' does not conform to protocol 'Foo'
//                Note: protocol requires function 'bar()' with type '() -> CGFloat'; do you want to add a stub?
struct Bad: Foo {
    //            vvvvvv <== not the same as CGFloat here?
    func bar() -> Double { 0 }      // note: candidate has non-matching type '() -> Double'
}

Xcode Version 13.0 beta 5 (13A5212g)

Yes, Float, Double and CGFloat are three distinct types and require explicit conversion between each other

CGFloat and Double should be interchangeable since this has been implemented in Swift 5.5:

1 Like

Only in expressions, they cannot be used be used to satisfy protocol requirements.

1 Like

Do you know where it say this?

The following works, isn't this also "protocol requirements"?

import UIKit

protocol FooFoo {
    func bar(_ arg: CGFloat)
}

struct FooFooGood {
    func bar(_ arg: Double) { }
}

It seems only function return type is problematic, not consistent.

In Detailed Design in mentions locations suitable for conversion. Neither protocol requirements nor overloading do form a conversion.

1 Like

FooFooGood does not conform to protocol FooFoo, in your example. So, the two func bars are distinct. Even if you add the conformance, FooFooGood::bar does not satisfy the protocol requirement, it simply defines an overload of bar that takes a Double as an argument for struct FooFooGood only.

1 Like

My mistake 🤦, it should be this and it also doesn't compile so it's consistent:

struct FooFooGood: FooFoo {
    func bar(_ arg: Double) { }
}
Terms of Service

Privacy Policy

Cookie Policy