Luk*_*ger 6 arrays generics swift
我在将通用类型的结构放入一个数组时遇到问题。我知道Swift会将Array的元类型转换为具体类型,这就是冲突。我试图找到其他解决方案,但我认为需要您的帮助。
在这里,我定义了结构和协议:
protocol ItemProtocol {
var id: String { get }
}
struct Section<T: ItemProtocol> {
var items: [T]
var renderer: Renderer<T>
}
struct Renderer<T> {
var title: (T) -> String
}
Run Code Online (Sandbox Code Playgroud)
这里有两个实现的示例结构ItemProtocol:
struct Book: ItemProtocol {
var id: String
var title: String
}
struct Car: ItemProtocol {
var id: String
var brand: String
}
Run Code Online (Sandbox Code Playgroud)
这是我设置部分的方式:
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)"
})
Run Code Online (Sandbox Code Playgroud)
现在,我想将各个部分放在一起。这是我尝试过的。但是这三行都给我一个错误:
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)")
})
})
Run Code Online (Sandbox Code Playgroud)
对于sections数组的声明,我得到此错误:
不支持将“ ItemProtocol”用作符合协议“ ItemProtocol”的具体类型
对于sections2数组的声明,此错误:
无法将“ Section”类型的值转换为预期的元素“ Section”类型
并sections3抛出这个:
期望'>'来完成通用参数列表
Any问题是不同Section类型(具有不同的泛型参数)之间没有共同点(除了)。一种可能的解决方案是将所有Section类型统一到一个协议中,并使用该协议来构建数组:
protocol SectionProtocol {
var genericItems: [ItemProtocol] { get }
var renderedTitles: [String] { get }
}
extension Section: SectionProtocol {
var genericItems: [ItemProtocol] { return items }
var renderedTitles: [String] {
return items.map { renderer.title($0) }
}
}
let sections: [SectionProtocol] = [bookSection, carSection]
sections.forEach { section in
section.renderedTitles.forEach { renderedTitle in
print("\(renderedTitle)")
}
}
Run Code Online (Sandbox Code Playgroud)
因此,您不需要迭代元素,而是迭代渲染的标题,每个部分都应该能够构建这些标题。
现在,这解决了您问题中的基本用例,但是,根据您在应用程序中使用该部分的情况,这可能还不够,您必须求助于键入橡皮擦,正如其他回答者提到的那样。
| 归档时间: |
|
| 查看次数: |
562 次 |
| 最近记录: |