无法满足协议要求

时间:2018-04-03 16:02:41

标签: swift protocols

我想在watchOS,iOS和TvOS上创建一个视图协议,所以我可以通用的方式获取他们的子视图和超级视图。

起初我试过这个:

protocol ViewProtocol: Hashable {
    var superview: Self? { get }
    var subviews: [Self] { get }
}

然后我像这样扩展UIView类:

extension UIView: ViewProtocol {}

但是我从编译器中得到了这个错误:

<unknown>:0: error: protocol 'ViewProtocol' requirement 'superview' cannot be satisfied by a non-final class ('UIView') because it uses 'Self' in a non-parameter, non-result type position

我不能理解这个问题(我认为这与编译器无法在非最终类中使用Self有关),所以我尝试了以下内容:

协议如下所示:

protocol ViewProtocol: Hashable {
    func getSuperview() -> ViewProtocol?
    func getSubviews() -> [ViewProtocol]
}

但是现在我在协议声明中得到了这个错误:

Protocol 'ViewProtocol' can only be used as a generic constraint because it has Self or associated type requirements

所以我尝试了这个:

protocol ViewProtocol: Hashable {
    func getSuperview<T: ViewProtocol>() -> T?
    func getSubviews<T: ViewProtocol>() -> [T]
}

实现看起来像这样:

extension UIView: ViewProtocol {
    func getSuperview<T>() -> T? where T : ViewProtocol {
        return self.superview as! T?
    }

    func getSubviews<T>() -> [T] where T : ViewProtocol {
        return self.subviews as! [T]
    }
}

但是现在当我尝试在泛型类型ViewProtocol上使用该方法时,我收到此错误:Generic parameter 'T' could not be inferred

有人能帮助我吗?我想从根本上理解这里发生了什么以及为什么要这么做很难?

1 个答案:

答案 0 :(得分:1)

在非最终课程中你不能有Self的要求,这里有一个例子来说明为什么这没有意义:

protocol Copyable {
    var copyOfSelf: Self { get }
}

final class Car {
    let name: String
    init(name: String) { self.name = name }
}

extension Car: Copyable {
    var copyOfSelf: Car { return Car(name: self.name) }
}

class SportsCar: Car {
    // Inherited:
    // var copyOfSelf: Car { return Car(name: self.name) }
    // Notice that it still returns `Car`, not `SportsCar`,
    // Breaking the conformance to `Copyable`
}