【问题标题】:Setting protocol which inherits from another protocol as associated type produces error将从另一个协议继承的协议设置为关联类型会产生错误
【发布时间】:2020-06-18 18:08:44
【问题描述】:

我正在尝试学习协议和相关类型。我有几个声明关联类型的协议,从:

protocol MasterViewModel {
    associatedtype Item: AWMediaItem
...
}

AWMediaItem 是另一个协议

protocol AWMediaItem {
    var name: String { get }
    var source: AWMediaSource { get }
}

AWAlbum 是另一个继承自 AWMediaItem 的协议

protocol AWAlbum: AWMediaItem {
    var albumName: String { get }
...
}

由于某种原因,在实现MasterViewModel 协议的类中,我无法将 AWAlbum 设置为Item

final class AlbumsMasterViewModel: MasterViewModel {
    typealias Item = AWAlbum // Error
...
}

我得到的警告是

  1. 可能有意匹配“AlbumsMasterViewModel.Item”(又名“AWAlbum”)不符合“AWMediaItem”

如果我理解正确,所有AWAlbum's 都会实现AWMediaItem 那么为什么这不起作用?

【问题讨论】:

  • AWMediaItemnamesource的实现在哪里?即使在某个基于协议的环境中,也必须实现协议要求。
  • 在实现此协议的结构/类中。我认为在这种情况下没有任何区别

标签: ios swift protocols


【解决方案1】:

我想你是想写

final class AlbumsMasterViewModel<Item: AWAlbum>: MasterViewModel {
    
}

我假设当你写的时候:

    typealias Item = AWAlbum // Error

您希望AlbumsMasterViewModel 的项目符合您的AWAlbum 协议,但您只需创建一个typelias,这意味着Item 只是AWAlbum 的别名。

如果你想使用类型别名,你需要一个符合AWMediaItem 的具体类型,而不是继承自它的协议。例如:

class ConcreteAlbum: AWAlbum {
    var albumName: String
    var name: String
    var source: AWMediaSource
    ...    
}

final class AlbumsMasterViewModel: MasterViewModel {
    typealias Item = ConcreteAlbum // No Error
}

编辑

如果您想将AlbumsMasterViewModel 与多个Item 类型一起使用,您也可以这样声明:

final class AlbumsMasterViewModel<Item: AWMediaItem>: MasterViewModel {
    
}

【讨论】:

  • 不幸的是,这对我没有帮助。 AWAlbum 是一个协议,很少有类符合它,所以我可以将它们全部显示在我的视图中。创建另一个类会添加另一个不必要的层 IMO。我不明白为什么我的解决方案不能工作,从另一个协议继承可以保证基本协议要求得到满足。太可惜了,还是谢谢
  • 自从我测试我的代码而你没有共享任何符合AWAlbum的类型我不得不创建我的示例工作的虚拟混凝土类型。您只需将ConcreteAlbum 替换为您已经拥有的几个类中的任何一个,它是一个模拟对象,而不是解决方案的一部分;)
  • 是的,但是假设我有 AlbumA 和 AlbumB 类型的对象,并且这两种类型都符合 AWAlbum 协议。我不明白如何通过使用协议和类型别名来使用这两种类型:/
  • 不能使用类型别名,但可以使用泛型类型
  • 修改代码后出现错误并不奇怪。特别是如果您将非泛型类设为泛型。正如我所说,你应该编辑这篇文章以提供反馈并分享你得到的错误(调试细节),或者创建一个新的,但我不知道你将如何做没有泛型或多个符合类的事情。但要明确的是,typealias Item = AWAlbum 可能永远不会像你认为的那样工作,如果 AWAlbum 是一个协议
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-14
  • 2021-09-21
  • 2022-11-27
  • 1970-01-01
  • 1970-01-01
  • 2018-02-25
相关资源
最近更新 更多