简体   繁体   English

具有关联类型和泛型的Swift协议调用了错误的函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM