具有相同关联类型名称的协议

Fra*_* Yu 5 associated-types swift swift-protocols

如果我有两个协议,其关联类型恰好相同,例如

protocol Read {
    associatedtype Element
    func read() -> Element
}
protocol Write {
    associatedtype Element
    func write(a: Element)
}
Run Code Online (Sandbox Code Playgroud)

然后我想要一个类来读取整数并将字符串写入:

class ReadWrite: Read, Write {
    func read() -> Int {
        return 5
    }
    func write(a: String) {
        print("writing \(a)")
    }
}
Run Code Online (Sandbox Code Playgroud)

但编译器抱怨并建议更改StringInt. 理想情况下,应该推断类型,或者至少在我显式声明时编译

associatedtype Read.Element = Int
associatedtype Write.Element = String
Run Code Online (Sandbox Code Playgroud)

之内ReadWrite。有解决办法吗?

更新

受此问题启发的解决方法是创建两个辅助协议

protocol ReadInt: Read {
    associatedtype Element = Int
}
protocol WriteString: Write {
    associatedtype Element = String
}
Run Code Online (Sandbox Code Playgroud)

并让该类继承这两个类:

class ReadWrite: ReadInt, WriteString {
    func read() -> Int {
        return 5
    }
    func write(a: String) {
        print("writing \(a)")
    }
}
Run Code Online (Sandbox Code Playgroud)

这似乎可以编译,但我担心这种方式会出现任何问题。

再次更新

我在 Swift 的问题跟踪器中发现了这个问题。任何需要这个缺失功能​​的人(比如我)都应该投票支持它。作为比较,这种模式在Rust中是可能的,它也支持关联类型(尽管这不是惯用用法)。

Mik*_*rne 1

另一种解决方法是创建第三个组合协议:

protocol ReadWrite {
    associatedtype R
    associatedtype W
    func read() -> R
    func write(a: W)
}
Run Code Online (Sandbox Code Playgroud)

它并不漂亮,因为它迫使您重新声明协议成员,但它确实保持了它的通用性(您不限于 String 和 Int)。