I have tried to keep my question very simple. I have been struggling whole day to make it work but no luck. I have two protocols. Decodable and Requestable.
protocol Decodable { }
struct D: Decodable { }
protocol Requestable {
associatedtype Model
}
extension Requestable {
func returnValue() {
Utils.doSomething(Model)
}
}
And a class Utils
class Utils {
static func doSomething<T>(param: T) {
print("Default")
}
static func doSomething<T: Decodable>(param: T) {
print("Decodable")
}
static func doSomething<T: Decodable>(param: [T]) {
print("Decodable Array")
}
}
I create a struct R implementing Requestable and give the type alias Model to String
struct R: Requestable {
typealias Model = String
}
When i run the R().returnValue() function, It prints Default
. As Expected.
I create a struct R2 implementing Requestable and give the type alias Model to D which is implementing Decodable
struct R2: Requestable {
typealias Model = D
}
When i run the R2().returnValue() function, It prints Default
. but i was expecting it would print Decodable
because the Model D
conforms to Decodable
.
I create a struct R3 implementing Requestable and give the type alias Model to [D] where the element of array is implementing Decodable
struct R3: Requestable {
typealias Model = [D]
}
When i run the R3().returnValue() function, It prints Default
. but i was expecting it would print Decodable Array
because the Model D
conforms to Decodable
.
Any kind of help appreciated.
UPDATE
Using AnyRequestable and checking in runtime will not work in this case because in real code the Generic is the return value and could not be checked dynamically.
In real code functions signatures are like
public static func ResponseSerializer<M>() -> ResponseSerializer<M, NSError> {}
public static func ResponseSerializer<M: Decodable>() -> ResponseSerializer<M, NSError> {}
public static func ResponseSerializer<M: Decodable>() -> ResponseSerializer<[M], NSError> {}
This is the expected result. You forgot to declare the Decodable
conformance for your Model
associated type. This should fix it:
protocol Requestable {
associatedtype Model: Decodable
}
Edit: Reading your comments, I now understand your problem. The thing is, what you're asking of requires the runtime, there is no way to statically achieve it:
class Utils {
static func doSomething<T>(param: T) {
if let param = param as? Decodable {
print("Decodable")
} else {
print("Default")
}
}
}
Think about it; when you are compiling your code, in the scope of returnValue
, the compiler only knows that Model
is an associated type and nothing else. Either you explicitly declare the conformance Decodable
, or the compiler assumes the default case, which is just <T>
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.