首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过指定类型将“带有关联类型的协议”转换为常规协议

通过指定类型将“带有关联类型的协议”转换为常规协议
EN

Stack Overflow用户
提问于 2018-12-19 11:55:56
回答 2查看 54关注 0票数 2

我有以下协议:

代码语言:javascript
复制
protocol PieceViewGateway {
    subscript(_ identifier: PieceIdentifier) -> UIView {get}
}

我在很多地方都用这样的方式:

代码语言:javascript
复制
struct SomeKindOfThing {
  let viewGateway: PieceViewGateway
}

这一切都很好很好。

下面是协议具体实现的一个示例(还有其他实现):

代码语言:javascript
复制
struct ViewDictionaryPieceViewGateway: PieceViewGateway {
    let viewDictionary: [PieceIdentifier: UIView]

    subscript(identifier: PieceIdentifier) -> UIView {
        guard let item = viewDictionary[identifier] else { 
          fatalError("Gateway has no value for key: \(identifier)") 
        }

        return item
    }
}

我有几个类似的协议。另一个是PieceValueGateway,它返回一个Int而不是一个UIView

我不想为我需要网关的各种不同的“方面”实现类似ViewDictionaryPieceViewGateway的东西。

我试图通过定义一个具有关联类型的协议来建立网关模型,从而实现这一目标:

代码语言:javascript
复制
protocol PieceAspectGateway {
    associatedtype Aspect
    subscript(_ identifier: PieceIdentifier) -> Aspect {get}

}

然后,我将PieceViewGateway与以下内容保持一致:

代码语言:javascript
复制
protocol PieceViewGateway: PieceAspectGateway {
    subscript(_ identifier: PieceIdentifier) -> UIView {get}
}

但是,这会产生许多编译错误,这些错误如下:

协议'PieceViewGateway‘只能用作泛型约束,因为它具有自或关联的类型要求

在我添加一致性PieceViewGateway: PieceAspectGateway之前,代码中会报告这些错误。SomeKindOfThing宣布它有一个let viewGateway: PieceViewGateway

我也试过这样做:

代码语言:javascript
复制
protocol PieceViewGateway: PieceAspectGateway where Aspect == UIView {
    subscript(_ identifier: PuzzlePieceIdentifier) -> UIView {get}
}

就像这样:

代码语言:javascript
复制
protocol PieceViewGateway: PieceAspectGateway {
    typealias Aspect = UIView
    subscript(_ identifier: PuzzlePieceIdentifier) -> UIView {get}
}

…但是,当PieceViewGateway用作协议时,所有这些变体都会产生相同的错误。

有什么办法可以做到这一点吗?

谢谢。

EN

回答 2

Stack Overflow用户

发布于 2018-12-19 12:45:01

您可以使用protocolassociatedtype和类型橡皮擦一起创建任何类型的Gateway。请看下面,

代码语言:javascript
复制
protocol PieceAspectGateway {
    associatedtype Aspect
    subscript(_ identifier: PieceIdentifier) -> Aspect {get}

}

struct AnyGateway<T>: PieceAspectGateway {
    let dictionary: [PieceIdentifier: T]

    subscript(identifier: PieceIdentifier) -> T {
        guard let item = dictionary[identifier] else {
            fatalError("Gateway has no value for key: \(identifier)")
        }
        return item
    }
}

使用

代码语言:javascript
复制
let viewGateway: AnyGateway<UIView>
let viewGateways: [AnyGateway<UIView>] = []

let intGateway: AnyGateway<Int>
let intGateways: [AnyGateway<Int>] = []

let stringGateway: AnyGateway<String>
let stringGateways: [AnyGateway<String>] = []
票数 1
EN

Stack Overflow用户

发布于 2018-12-19 12:50:26

您想要完成的任务非常简单:

代码语言:javascript
复制
protocol PieceAspectGateway {
    associatedtype Aspect
    subscript(_ identifier: PieceIdentifier) -> Aspect {get}
}

所以你有这个协议。当您想从它继承并使用更特定的类型时,可以使用泛型约束:

代码语言:javascript
复制
protocol IntPieceAspectGateway: PieceAspectGateway where Aspect == Int {
    ...
}
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53850726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档