静态成员不能在协议元类型Swift上使用

Ale*_*lex 31 ios swift

我正在尝试为我拥有的协议类型创建一个闭包,但是我收到以下错误

静态成员'menuItemSorter'不能用于协议元类型'MenuItem.Protocol'

这是我试图在操场上运行的代码的简化版本.

protocol MenuItem {
    var order: Int {get}
}

extension MenuItem {
    static var menuItemSorter: (MenuItem, MenuItem) -> Bool {
        return { $0.order < $1.order }
    }
}

class BigItem : MenuItem {
    var order: Int = 1
}

let bigItems = [BigItem(), BigItem()]

let sorter = MenuItem.menuItemSorter
Run Code Online (Sandbox Code Playgroud)

我希望能够在MenuItem上有一个类/静态var方法,可以对menuItems进行排序,这是最好的方法吗?

Str*_*ers 38

协议没有其他代码的可访问接口.

您需要从粘贴类型中调用它:

class BigItem: MenuItem {
    var order: Int = 1
}

let sorter = BigItem.menuItemSorter
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.从Swift看起来对我来说是一种愚蠢的限制.也许我会为静力学引入顶级的一致性类型. (6认同)
  • @MattD功能不是一个bug.这违背了协议的想法.协议不是结构或类,它是类型使用和声明遵守某组功能的一种方式.允许仅由协议拥有的存储或功能将破坏许多当前规则,并破坏协议和类之间的任何有意义的差异. (6认同)
  • @PeejWeej既然是静态的,它实际上并不意味着以与类相同的方式进行存储,它只是在限制对静态变量或函数的访问。当您有一个提供某些类“ MyClass”的框架,并且也有“ MyClassImpl”但想从客户端代码中隐藏“ MyClassImpl”时,这将是非常不错的。MyClass可以具有静态函数public static func create(...)-&gt; MyClassImpl,该函数实际上构造并返回实现,从而允许客户端代码不依赖于MyClassImpl,而且可以方便地访问创建方法一 (4认同)
  • @wfbarksdale 它可能不一定意味着“存储”,但它肯定意味着所有权。它必须存在于运行时的某个地方,并且由(当前)拥有 0 所有权能力的协议拥有。允许协议定义逻辑和/或拥有所有权将使协议与抽象类非常相似,而不是它们目前的特殊花。也许它应该/将在某个时候添加,但是它试图解决的问题可能有更好的解决方案(例如上述抽象类)。在那之前它有点只是自行车脱落:) (2认同)
  • 由于我们可以在协议扩展中拥有默认的协议实现和计算属性,因此我们也会期望这一点。也许是快速进化过程提案? (2认同)