首页 文章

Swift协议强制Equatable协议

提问于
浏览
4

我已经定义了2个协议 . 我需要第一个(NameProtocol)来强制执行Equatable协议 . 而另一个类(BuilderProtocol)有一个方法返回第一个(NameProtocol) .

public protocol NameProtocol : Equatable {
    var name: String { get }
}

public protocol BuilderProtocol {
    func build() -> NameProtocol? // Compiler error
    init()
}

编译器错误:“协议'NameProtocol'只能用作通用约束,因为它具有Self或关联类型要求”

我需要通过build()返回一个对象来返回一个符合NameProtocol的对象,我可以在其上定义==

有没有办法让这项工作成功?

谢谢


如果在BuilderProtocol中使用typealias,我如何使数组声明工作?

public protocol OtherRelatedProtocol {
    var allNames : Array<NameProtocol> { get }
}

Conclusion

我将删除Equatable并实现一个isEqual方法 .

public protocol NameProtocol {
    func isEqual(nameable: NameProtocol) -> Bool
    var name: String { get }
}

1 回答

  • 3

    如果您熟悉Java或C#,Swift协议大约在泛型和接口之间 . 例如,您可以在协议中执行的一项操作是:

    protocol Foo {
        func compareWith(foo: Self)
    }
    

    实现此协议的类将具有接受其自己类型的对象(而不是 Foo 类型的对象)的方法 compareWith .

    这就是编译器调用的"Self or associated type requirements",这就是定义Equatable的方式(它需要一个接受两个 Self 操作数的 operator== ) . 但是,这些协议的缺点是您只能将它们用作通用约束:您不能将它们用作表达式类型 .

    解决方案是使用泛型 . 在这种情况下,您将使 ProtocolBuilder 协议具有通用性,并使用该类型实现 NameProtocol 的约束 .

    public protocol NameProtocol : Equatable {
        var name: String { get }
    }
    
    public protocol BuilderProtocol {
        typealias T: NameProtocol
        func build() -> T?
        init()
    }
    

相关问题