gpt4 book ai didi

arrays - Swift 中的异构通用容器

转载 作者:搜寻专家 更新时间:2023-10-30 22:14:41 24 4
gpt4 key购买 nike

我在将具有泛型类型的结构放入一个数组时遇到问题。我知道 Swift 将数组的元类型转换为具体类型,这就是冲突。我试图找到不同的解决方案,但我想我需要你的帮助。

这里我定义了结构和协议(protocol):

protocol ItemProtocol {
var id: String { get }
}

struct Section<T: ItemProtocol> {
var items: [T]
var renderer: Renderer<T>
}

struct Renderer<T> {
var title: (T) -> String
}

这里有两个实现 ItemProtocol 的示例结构:

struct Book: ItemProtocol {
var id: String
var title: String
}

struct Car: ItemProtocol {
var id: String
var brand: String
}

这就是我设置这些部分的方式:

let book1 = Book(id: "1", title: "Foo")
let book2 = Book(id: "2", title: "Bar")
let books = [book1, book2]
let bookSection = Section<Book>(items: books, renderer: Renderer<Book> { (book) -> String in
return "Book title: \(book.title)"
})
let car1 = Car(id: "1", brand: "Foo")
let car2 = Car(id: "2", brand: "Bar")
let cars = [car1, car2]
let carSection = Section<Car>(items: cars, renderer: Renderer<Car> { (car) -> String in
return "Car brand: \(car.brand)"
})

现在我想把这些部分放在一起。这是我试过的。但是这 3 行中的每一行都给我一个错误:

let sections: [Section<ItemProtocol>] = [bookSection, carSection]
let sections2: [Section] = [bookSection, carSection]
let sections3: [Section<AnyObject: ItemProtocol>] = [bookSection, carSection]

sections.forEach({ section in
section.items.forEach({ item in
let renderedTitle = section.renderer.title(item)
print("\(renderedTitle)")
})
})

对于 sections 数组的声明,我得到了这个错误:

Using 'ItemProtocol' as a concrete type conforming to protocol 'ItemProtocol' is not supported

对于 sections2 数组的声明这个错误:

Cannot convert value of type 'Section' to expected element type 'Section'

sections3 抛出这个:

Expected '>' to complete generic argument list

最佳答案

Section 结构是通用的,因此您不能将其用作类型。一种解决方案是使用类型删除:

创建任何 ItemProtocol 包装器:

protocol ItemProtocol {
var id: String { get }
}

struct AnyItem : ItemProtocol {

private let item: ItemProtocol

init(_ item: ItemProtocol) {
self.item = item
}

// MARK: ItemProtocol
var id: String { return item.id }
}

还有一个类型删除的部分,任何部分:

protocol SectionProtocol {
associatedtype T
var items: [T] { get }
var renderer: Renderer<T> { get }
}

struct Section<Item: ItemProtocol>: SectionProtocol {
typealias T = Item
var items: [Item]
var renderer: Renderer<Item>

var asAny: AnySection {
return AnySection(self)
}
}

struct AnySection : SectionProtocol {
typealias T = AnyItem

private let _items: () -> [T]
private let _renderer: () -> Renderer<T>

var items: [T] { return _items() }
var renderer: Renderer<T> { return _renderer() }

init<Section : SectionProtocol>(_ section: Section) {
self._items = { section.items as! [AnySection.T] }
self._renderer = { section.renderer as! Renderer<AnySection.T>}
}
}

现在你可以拥有一个 AnySection 的集合:

let sections: [AnySection] = [bookSection.asAny, carSection.asAny]

关于arrays - Swift 中的异构通用容器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49252213/

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