从数组中一般调用的 swift 静态协议函数

问题描述 投票:0回答:1

我有一个项目,我想以某种方式按结构进行记录。每个结构都应该有一个返回字符串的静态方法文档。我想为

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有关,但我不知道该怎么做..

swift types casting protocols extension-methods
1个回答
4
投票

您的代码在单一类型

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()
    

© www.soinside.com 2019 - 2024. All rights reserved.