我有一个项目,我想以某种方式按结构进行记录。每个结构都应该有一个返回字符串的静态方法文档。我想为
Array
编写一个扩展,以便我可以在符合我的协议的对象数组上调用该函数,但它不起作用..
到目前为止我得到了这个:
protocol Documentable {
static func document() -> String
}
extension Array: Documentable where Element == Documentable {
static func document() -> String {
guard let casted = Element.Type.self as? Documentable.Type else {
return "didn't work..."
}
return "[\(casted.document()), ...]"
}
}
struct StructA: Documentable {
static func document() -> String {
return "a"
}
}
// approach 1
// this leads to "didn't work..."
let a = Array<StructA>()
print(type(of: a).document())
// approach 2
// referencing static method 'document()' on 'Array' requires the types 'StructA' and 'any Documentable' be equivalent
let b = Array<StructA>.self
print(b.document())
方法 1 可以编译,但会导致运行时错误,因为强制转换在某种程度上不起作用,我觉得这没有什么意义,因为
Element
必须符合我的协议,所以强制转换应该始终有效..
方法 2 无法编译,并显示以下消息:
referencing static method 'document()' on 'Array' requires the types 'StructA' and 'any Documentable' be equivalent
这也很奇怪,因为
StructA
确实符合我的协议..
它可能与this有关,但我不知道该怎么做..
您的代码在单一类型
Array<Document>
上添加扩展,而不是为所有符合 Array<T>
的 T
添加扩展。Document
显然不能存在于
Element.document()
。由于 Array<Document>
与 Element
相同,因此 Document
没有实现。另请参阅您链接的帖子。 您应该将
Element.document()
更改为
==
。这可能就是你的意思。:
现在你可以做
extension Array: Documentable where Element: Documentable {
static func document() -> String {
"[\(Element.document()), ...]"
}
}
,这将返回
Array<StructA>.document()
。