gpt4 book ai didi

swift - associatedType 在另一个 associatedType 中使用协议(protocol)

转载 作者:搜寻专家 更新时间:2023-11-01 07:13:01 24 4
gpt4 key购买 nike

我一直在努力寻找在另一个关联类型中使用泛型和关联类型来解决上述问题的解决方案

案例

我想要一个ObjectRequestType,它里面有一个关联类型ObjectResponseType

protocol ObjectRequestType {
associatedtype Response: ObjectResponseType
}
另一方面,

ObjectResponseType 是一个具有关联类型 Element

的协议(protocol)
protocol ObjectResponseType {
associatedtype Element
}

我想要实现的是,我想根据不同类型的元素扩展 ObjectRequestType 的功能,这里为了示例我们有两种不同类型的 Element

protocol ElementType {}
protocol OtherElementType {}

到目前为止,我将通过以下扩展来实现这一点

extension ObjectRequestType where Response.Element: ElementType {
static func request() {
print("ElementType")
}
}

extension ObjectRequestType where Response.Element: OtherElementType {
static func request() {
print("OtherElementType")
}
}

额外的步骤是处理将此请求传递给我需要使用泛型的类

class DemoClass<Request: ObjectRequestType> {
static func execute() {
Request.request()
}
}

问题

由于 DemoClass 无法定义 Request 有什么样的 Response ,所以它会找到它的两个实现,并且会失败抛出编译错误

error: ambiguous reference to member 'request()'

通过添加额外的 where 子句来修改类仍然行不通,因为我会错过 OtherElementType 的其余实现

class DemoClass<Request: ObjectRequestType> where Request.Response.Element: ElementType {
static func execute() {
Request.request()
}
}

我一直在尝试解决这个问题,但我仍然无法实现这种情况。如果有人有任何想法或其他方法,我们将非常欢迎。

最佳答案

通常的做法是将 request 方法添加到 ObjectResponseType 协议(protocol)中,这样您就可以保证它存在于任何符合的类型上。然后你创建一个协议(protocol)扩展,为你知道如何处理的类型提供默认实现,你已经完成了。如果您需要使用现有元素类型之一覆盖某个请求的请求,您可以这样做。如果您需要支持其他元素类型,您可以直接在请求中执行或添加其他协议(protocol)扩展。

protocol ObjectResponseType {
associatedtype Element
}
protocol ObjectRequestType {
associatedtype Response: ObjectResponseType

static func request()
}

protocol ElementType {}

extension ObjectRequestType where Response.Element: ElementType {
static func request() {
print("ElementType")
}
}
protocol OtherElementType {}
extension ObjectRequestType where Response.Element: OtherElementType {
static func request() {
print("OtherElementType")
}
}

class DemoClass<Request: ObjectRequestType> {
static func execute() {
Request.request()
}
}

class Foo: ElementType {}
class FooResponse: ObjectResponseType {
typealias Element = Foo
}
class FooRequest: ObjectRequestType {
typealias Response = FooResponse
}

class Bar: OtherElementType {}
class BarResponse: ObjectResponseType {
typealias Element = Bar
}
class BarRequest: ObjectRequestType {
typealias Response = BarResponse
// Override the default implementation
static func request() {
print("Bar")
}
}

class Baz {}
class BazResponse: ObjectResponseType {
typealias Element = Baz
}
class BazRequest: ObjectRequestType {
typealias Response = BazResponse

static func request() {
print("Baz")
}
}

DemoClass<FooRequest>.execute() // ElementType
DemoClass<BarRequest>.execute() // Bar
DemoClass<BazRequest>.execute() // Baz

关于swift - associatedType 在另一个 associatedType 中使用协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43925216/

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