gpt4 book ai didi

swift - 为什么这不像我期望(希望)的那样表现?

转载 作者:行者123 更新时间:2023-11-28 07:50:11 28 4
gpt4 key购买 nike

我在我的框架中设置了几个协议(protocol)来处理资源。在其中一个协议(protocol)中,我设置了一个扩展来为 decode 函数提供默认实现。显示代码和发生的情况更简单(请参阅对 fatalError 的调用)。实际实现中还有很多代码,但这说明了问题:

这是“基础”协议(protocol):

public protocol Resourceful {
associatedtype AssociatedResource
typealias ResourceCompletionHandler = (AssociatedResource?, Error?) -> Void

func fetch(_ completion: @escaping ResourceCompletionHandler)
}

这是 Resourceful 的通用具体实现:

    open class WebResourceApiCall<Resource>: Resourceful {
public typealias AssociatedResource = Resource
public typealias FetchedResponse = (data: Data?, urlResponse: URLResponse?)

public init() {
}

public func fetch(_ completion: @escaping ResourceCompletionHandler) {
try! decode(fetched: (data: nil, urlResponse: nil))
}

public func decode(fetched: FetchedResponse) throws -> Resource {
fatalError("It ends up here, but I don't want it to!")
}
}

extension WebResourceApiCall where Resource: Decodable {
public func decode(fetched: FetchedResponse) throws -> Resource {
fatalError("This is where I want it to go...")
}
}

这就是我尝试使用它的方式:

public struct Something: Decodable { }

var apiCall = WebResourceApiCall<Something>()
apiCall.fetch { _, _ in } // Implictly calls decode... but not the decode I expected it to! See fatalError() calls...

不是像我希望的那样在扩展上调用decode,而是始终调用没有约束的“默认”decode 方法。

为什么这不像我期望的那样工作?

提前致谢!

最佳答案

Swift 是一种静态调度语言,因此要调用的 decode() 函数的地址是在编译时计算的,并且由于调用发生在类的基定义中,编译器选择原始实现。

现在,如果您从编译器有足够信息来选择您需要的实现的地方调用该方法,它将起作用:

var apiCall = WebResourceApiCall<Something>()
try apiCall.decode(fetched: (nil, nil))

上面的代码将从专用扩展调用方法,因为此时编译器可以更好地知道它有一个更专用的实现来调用。

如果您在动态调度世界中移动 decode() 方法,应该可以实现您需要的行为 - 即在协议(protocol)级别。

关于swift - 为什么这不像我期望(希望)的那样表现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49924478/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com