我正在使用Swift 3.1并且有一些通用结构:
struct Section<InfoT: Equatable, ItemsT: Equatable> {
let info: InfoT?
let items: [ItemsT]
}
并希望使用自定义方法对此泛型类型的元素进行数组扩展:
extension Array where Element == Section<Equatable, Equatable> {
// Just dummy example function:
func debugDummy() {
for section in self {
let info = section.info
print("section info: \(info).")
for item in section.items {
print("item: \(item).")
}
}
}
}
这给了我编译错误:
error: using 'Equatable' as a concrete type conforming to protocol 'Equatable' is not supported
extension Array where Element == Section<Equatable, Equatable> {
^
error: GenericsListPlayground.playground:6:24: error: value of type 'Element' has no member 'info'
let info = section.info
^~~~~~~ ~~~~
error: GenericsListPlayground.playground:8:25: error: value of type 'Element' has no member 'items'
for item in section.items {
^~~~~~~ ~~~~~
如何正确宣布此类延期?我已尝试过几种变体来声明此扩展名,例如:
extension Array where Element == Section (no arguments)
产生
error: reference to generic type 'Section' requires arguments in <...>
等......他们都不想编译。
答案 0 :(得分:6)
试试这个:
each
答案 1 :(得分:3)
@ Eppilo回答的衍生物:
虽然Section协议一切都很好,但记住它的不同实现方式非常重要。
这是一个示例,显示了两个用例,复制并粘贴到操场上,以便Swift 3.1检查出来:)
protocol Section {
associatedtype InfoType: Equatable
associatedtype ItemsType: Equatable
var info: InfoType? { get set }
var items: [ItemsType] { get set }
}
// This struct will try to infer the types for info and items when instantiating an object, any type that conforms to Equatable can be used while instantiating.
struct InferredSection<Info: Equatable, Items: Equatable> : Section {
var info: Info?
var items: [Items]
}
// This struct has explicit types, which means you can ONLY instantiate an object from this by using the specified types within the struct.
struct ExplicitSection : Section {
typealias InfoType = String
typealias ItemsType = Int
var info: InfoType?
var items: [ItemsType]
}
extension Array where Element: Section {
// Just dummy example function:
func debugDummy() {
for section in self {
let info = section.info
print("section info: \(String(describing: info)).")
for item in section.items {
print("item: \(item).")
}
}
}
}
let explicit = ExplicitSection(info: "This section has explicit set types", items: [13, 37])
let inferred = InferredSection(info: "This section has inferred types", items: ["Foo", "Bar"])
let explicitTypeArray = [explicit, explicit]
let inferredTypeArray = [inferred, inferred]
explicitTypeArray.debugDummy()
inferredTypeArray.debugDummy()
// The Section protocol can only be used as a generic constraint since it has associatedType requirements, which means you can't mix different types that conforms to Section to the same array without changing the the type to Any
let all: [Section] = []
let mixedArray = [explicit, inferred] // Not allowed unless cast to [Any]