[英]Swift Protocols with Associated Type and Generics calling wrong function
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 我创建一个实现Requestable的结构R,并将类型别名Model赋予String
struct R: Requestable {
typealias Model = String
}
When i run the R().returnValue() function, It prints Default
. 当我运行R()。returnValue()函数时,它将显示
Default
。 As Expected. 不出所料。
I create a struct R2 implementing Requestable and give the type alias Model to D which is implementing Decodable 我创建一个实现Requestable的结构R2,并将类型别名Model赋予正在实现Decodable的D
struct R2: Requestable {
typealias Model = D
}
When i run the R2().returnValue() function, It prints Default
. 当我运行R2()。returnValue()函数时,它将显示
Default
。 but i was expecting it would print Decodable
because the Model D
conforms to Decodable
. 但是我期望它会打印
Decodable
因为Model D
符合Decodable
。
I create a struct R3 implementing Requestable and give the type alias Model to [D] where the element of array is implementing Decodable 我创建一个实现Requestable的结构R3,并将类型别名Model赋予[D],其中数组元素正在实现Decodable
struct R3: Requestable {
typealias Model = [D]
}
When i run the R3().returnValue() function, It prints Default
. 当我运行R3()。returnValue()函数时,它将显示
Default
。 but i was expecting it would print Decodable Array
because the Model D
conforms to Decodable
. 但我期望它会打印
Decodable Array
因为Model D
符合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. 在这种情况下,无法使用AnyRequestable并在运行时进行检查,因为在实际代码中,Generic是返回值,无法动态检查。
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. 您忘记为
Model
关联类型声明Decodable
一致性。 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. 在编译代码时,在
returnValue
范围内,编译器仅知道Model
是关联的类型,而没有其他东西。 Either you explicitly declare the conformance Decodable
, or the compiler assumes the default case, which is just <T>
. 您可以显式声明一致性
Decodable
,或者编译器采用默认情况,即<T>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.