具有相同关联类型名称的协议
protocol with same associated type name
如果我有两个协议的关联类型恰好相同,比如
protocol Read {
associatedtype Element
func read() -> Element
}
protocol Write {
associatedtype Element
func write(a: Element)
}
然后我想要一个 class 从中读取整数并将字符串写入:
class ReadWrite: Read, Write {
func read() -> Int {
return 5
}
func write(a: String) {
print("writing \(a)")
}
}
但编译器抱怨并建议将 String
更改为 Int
。理想情况下,应该推断类型,或者如果我明确声明
至少可以编译
associatedtype Read.Element = Int
associatedtype Write.Element = String
在 ReadWrite
内。有解决办法吗?
更新
受启发的解决方法是创建两个辅助协议
protocol ReadInt: Read {
associatedtype Element = Int
}
protocol WriteString: Write {
associatedtype Element = String
}
并让 class 从这两个继承:
class ReadWrite: ReadInt, WriteString {
func read() -> Int {
return 5
}
func write(a: String) {
print("writing \(a)")
}
}
这似乎可以编译,但我担心这样会遇到任何问题。
再次更新
我发现 the issue in Swift's issue tracker. Anyone require this missing feature (like me) should vote for it. As a comparison, this pattern is possible in Rust,它也支持关联类型(尽管这不是惯用的用法)。
另一种解决方法是创建第三个组合协议:
protocol ReadWrite {
associatedtype R
associatedtype W
func read() -> R
func write(a: W)
}
它并不漂亮,因为它迫使您重新声明协议成员,但它确实保持了它的通用性(您不限于 String 和 Int)。
如果我有两个协议的关联类型恰好相同,比如
protocol Read {
associatedtype Element
func read() -> Element
}
protocol Write {
associatedtype Element
func write(a: Element)
}
然后我想要一个 class 从中读取整数并将字符串写入:
class ReadWrite: Read, Write {
func read() -> Int {
return 5
}
func write(a: String) {
print("writing \(a)")
}
}
但编译器抱怨并建议将 String
更改为 Int
。理想情况下,应该推断类型,或者如果我明确声明
associatedtype Read.Element = Int
associatedtype Write.Element = String
在 ReadWrite
内。有解决办法吗?
更新
受
protocol ReadInt: Read {
associatedtype Element = Int
}
protocol WriteString: Write {
associatedtype Element = String
}
并让 class 从这两个继承:
class ReadWrite: ReadInt, WriteString {
func read() -> Int {
return 5
}
func write(a: String) {
print("writing \(a)")
}
}
这似乎可以编译,但我担心这样会遇到任何问题。
再次更新
我发现 the issue in Swift's issue tracker. Anyone require this missing feature (like me) should vote for it. As a comparison, this pattern is possible in Rust,它也支持关联类型(尽管这不是惯用的用法)。
另一种解决方法是创建第三个组合协议:
protocol ReadWrite {
associatedtype R
associatedtype W
func read() -> R
func write(a: W)
}
它并不漂亮,因为它迫使您重新声明协议成员,但它确实保持了它的通用性(您不限于 String 和 Int)。