Reputation: 359
I have a protocol with an associated Type
protocol ProtocolA {
associatedType someType
}
Now i have two generic functions
func funcA<someType>(_ data:someType) {
funcB(data) // cannot call
}
func funcB<someType:ProtocolA>(_ data:someType) {
}
I have been trying to call funcB from funcA, but it is not working I am getting the error
Instance method 'funcB' requires that 'someType' conform to 'ProtocolA'
Now i know for a fact that the Generic Type in funcA is conforming to ProtocolA. Is there anyway to also make sure that the compilers know it too ?
I cannot change the funcA method declaration to put a generic constraint as it is the requirement of another protocol.
I have tried using the some
keyword in funcA by doing
var obj : some ProtocolA = data
However i am getting the error
Property declares an opaque return type, but cannot infer the underlying type from its initializer expression
Basically in short is there anyway i can call funcB from funcA without changing funcA signature, however funcB signature can be changed to whatever is required
****EDIT*****Added More Information
funcA is called by the protocl
protocol CommonService {
func funcA<ModelType>(_ data:ModelType)
}
class CommonServiceImpl : CommonService {
func funcA<someType>(_ data:someType) {
funcB(data) // cannot call
}
func funcB<someType:ProtocolA>(_ data:someType) {
//SomeCode here required that someType must implement ProtocolA
}
}
ProtocolA is contained in a third party pod that cannot be changed.
*******Edit***********How i solved the problem
So thanks to @Mojtaba Hosseini in answers i got a really good idea on how to solve my problem.
I simply wrote an overloaded function in my CommonServiceProtocol
protocol CommonService {
func funcA<ModelType>(_ data:ModelType)
func funcA<ModelType>(_ data:ModelType) where ModelType:ProtocolA
}
class CommonServiceImpl : CommonService {
func funcA<someType>(_ data:someType) {
funcB(data) // cannot call
}
func funcA<someType>(_ data:someType) where ModelType:ProtocolA {
funcB(data) // can be called
}
func funcB<someType:ProtocolA>(_ data:someType) {
//SomeCode here required that someType must implement ProtocolA
}
}
I mean it is not a perfect solution but given the hard dependency on an associatedType using ProtocolA in a third party pod i would say it works alright and that is one of the reasons to avoid third party dependencies as much as possible.
Upvotes: 0
Views: 69
Reputation: 119128
Is there any way to also make sure that the compilers know it too?
You have to implement an overload for the funcA
and constraint it:
func funcA<someType>(_ data: someType) {
/* funcB(data) */ cannot call
print("Not detected")
}
func funcA<someType>(_ data: someType) where someType: ProtocolA {
funcB(data) // can call ✅
print("Detected")
}
so calling funcA("")
will result Not detected
but conforming to the protocol and calling the same function will result in Detected
// extension String: ProtocolA { typealias someType = String } // uncomment to see
funcA("")
Upvotes: 1
Reputation: 181
In functionB just add a parameter that will tell the compiler the type you expect, if you really want to be sure the type is your protocol add a check :
func transform<T>( data : T ){
guard let data = data as? Monster else {
print("data is not a monster type")
return
}
intoMonster(Monster.self, data: data)
}
func intoMonster<T> (_ type : T.Type , data : T){
}
Upvotes: 0
Reputation: 648
As per your requirement, I think you can match the signature of your funcB
with funcA
. Refer to the code below:
func funcA<someType>(_ data:someType) {
funcB(data)
}
func funcB<someType>(_ data:someType) {
}
As shown in the above code, you can remove the type constraint for someType in funcB.
Upvotes: 0