我可以在 ForEach 中使用协议数组吗?

Vla*_*ala 1 ios swift swiftui

我有一个带有两个实现它的类的协议:

protocol GalleryItem {
    func toView() -> AnyView
}

extension Class1:GalleryItem {
    func toView() -> AnyView {
      ...
    }
}

extension Class2:GalleryItem {
    func toView() -> AnyView {
      ...
    }
}
Run Code Online (Sandbox Code Playgroud)

数组:

var array:[GalleryItem] = [Class1(), Class2()]
Run Code Online (Sandbox Code Playgroud)

现在,如果我尝试在 ForEach 中使用该数组:

ForEach(array, id: \.self) { item in
  item.toView()
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

Value of protocol type 'GalleryItem' cannot conform to 'Hashable'; only struct/enum/class types can conform to protocols
Run Code Online (Sandbox Code Playgroud)

这是否意味着我不能将这样的协议数组传递给 ForEach?否则我将如何做到这一点?

Den*_*nis 7

好的,让我们让它工作。

问题

在您的情况下,编译器期望参数\.self为,Hashable并且此参数是您的协议的对象GalleryItem

解决方案

为了解决这个问题,我们可以在协议中添加一个可以提供\.id. 例如:

protocol GalleryItem {
    func toView() -> AnyView
    var id: Int { get }       // could be any `Hashable` type
}
Run Code Online (Sandbox Code Playgroud)

然后,\.self我们可以使用\.id作为标识符,而不是在 ForEach 中用作标识符:

ForEach(items, id: \.id) { item in
    item.toView()
}
Run Code Online (Sandbox Code Playgroud)

这里的命名和类型几乎取决于你。\.idInt用作示例。