如何在Swift 4中约束协议类型的参数以符合AnyObject?

时间:2018-10-02 05:33:16

标签: swift swift-protocols

非常接近查看以下内容:

// Note that this protocol can only be applied to reference types.
protocol Ref: class {
  var zibbles: Int { get set }
}

class Reference: Ref {
  var zibbles: Int = 42
}

// Note very carefully that we are NOT passing an
// instance, but a type itself.
func thwip<T: AnyObject>(into target: T.Type) {

}

// This compiles.
thwip(into: Reference.self)

// This fails to compile.
thwip(into: Ref.self) 

无论多么罕见,这都是语言应具有的完整性所能做的事情。编译器知道Ref的任何实例都必须符合AnyObject,因此对thwip的类型约束应该可以工作,但不能。

请注意,如果我们从AnyObject中删除thwip约束,则它会进行编译,但这违背了目的。我想知道传入的协议是否具有引用语义。

// thwip without AnyObject
func thwip<T>(into target: T.Type) {
}

// Compiles, but useless to me
thwip(into: Ref.self)

请注意,以下更改也无济于事:

// Here we've changed class to AnyObject
protocol Ref: AnyObject {
  var zibbles: Int { get set }
}

这是因为Ref: classRef: AnyObject是同义词。您可以通过将它们放在一起来确认这一点:

protocol Ref: class, AnyObject {}

尽管编译器仍会编译,但仍会警告您冗余的一致性。

请注意,有一个非常相似但众所周知的编译器错误:

protocol Base {}

protocol Ref: Base {}

func thwip<T: Base>(into target: T.Type) {
}

// Does not compile
thwip(into: Ref.self)

但是,在这种情况下,编译器给出的错误与我遇到问题的错误完全不同。就我而言,我得到“无法使用类型为'(type:Ref.Protocol)'的参数列表调用'thwip''”。在后一种情况下,我得到“在参数类型'Ref.Protocol'中,'Ref'不符合预期的类型'Base'”。

0 个答案:

没有答案