miku1958
(Miku1958)
1
In my project, there is an OC function that searches for Class that match a specific Protocol *object, now I want to write a swift version to limit the generic parameter is a protocol and return the same type, not AnyObject.
But I found that I can't, Swift will always return theProtocol.Protocol, here is the example:
public func classConforming<P>(to protocolName: P.Type) -> P.Type? {
// find the class
}
let theClass = classConforming(to: theProtocol.self)
// theClass: theProtocol.Protocol?
And I can't use the static functions in theProtocol, it only works when I return Any and cast it to theProtocol.Type
I also tried
public func classConforming<P: Protocol>(to protocolName: P) -> P.Type? {
// find the class
}
then theClass will become Protocol forever.
Anyone can help? Thanks
miku1958
(Miku1958)
2
I also tried
func classConforming<P, R>(to protocolName: P) -> R? where P: Protocol, R.Type == P { }
But it give me this error:
No type for 'P' can satisfy both 'P : AnyObject' and 'P == R.Type'
bbrk24
3
Protocol indicates an Objective-C protocol object, which is less flexible than Swift's metatypes.
There seems to be a difference in behavior with P.Type and P.Protocol that I don't fully understand:
1> protocol P {}
2> class C: P {}
3> C.self as? P.Type
$R0: P.Type? = P
4> C.self as? P.Protocol
$R1: P.Protocol? = nil
5> func classConforming<T>(to protocolName: T.Type) -> T.Type? { C.self as? T.Type }
6> classConforming(to: P.self)
$R2: P.Protocol? = nil
I wish there were some way to spell
func classConforming<T>(to protocolName: T.Protocol) -> some T.Type?
where T: protocol { ... }
Note the spelling T: protocol, which I intended to invoke a similar idea to C# where T: class, where T: struct. I did not say T: Protocol because, again, that means the Objective-C Protocol class.
I've wanted the ability to say this for other reasons too, like
func saveAsTypes<P1, P2, C>(first: P1.Protocol, second: P2.Protocol, object: C)
where C: P1 & P2
which isn't an unreasonable constraint on the face of it, but Swift has no spelling for.