实施具有不同关联类型的协议 [英] implement protocol with different associated type
问题描述
我有一个协议,我的快速代码库,我有一个具有关联类型和两种方法的协议.两种方法都为协议的关联类型定义了不同的通用约束.而且我想使该结构符合两种协议,但具有两种不同的关联类型.
I have a protocol my swift code base I have protocol with an associated type and two methods. Both of the methods define different generic constrains for the associated type of the protocol. And I would like to make the struct conform two the protocol but with two different associated types.
protocol Convertable {
associatedtype TargetType
func convert() -> TargetType
}
func show<T : Convertable where T.TargetType == String>(toShow : T) {
print(toShow.convert())
}
func add<T : Convertable where T.TargetType == Int>(a : T, b : T) -> Int {
return a.convert() + b.convert()
}
struct MyData {
var data : Int
}
作为扩展,我使该结构符合TargetType
将为String
的协议,以便将其传递给show方法:
As an extension I make the struct conform the protocol where the TargetType
will be String
in order to pass it to the show method:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
}
到目前为止,一切正常.但是现在,当TargetType
绑定到Int时,我还希望具有符合Convertable
协议的结构.哪个似乎不可能?
So far everything works as expected. But now I also like to have the struct to conform to the Convertable
protocol when TargetType
is bound to an Int. Which seems to be impossible?
我尝试做的第一件事是在扩展名中添加convert方法的第二个定义:
The first thing I tried was to add a second definition of the convert method to the extension:
extension MyData : Convertable {
func convert() -> String { return String(self.data) }
func convert() -> Int { return data }
}
编译器现在抱怨MyData
不再符合该协议.其次是将其拆分为两个扩展,并显式绑定TargetType.
The compiler now complains that MyData
does no longer conform to the protocol. Second was to split this into two extensions and bind the TargetType explicitly.
extension MyData : Convertable {
typealias TargetType = Int
func convert() -> Int { return data }
}
extension MyData : Convertable {
typealias TargetType = String
func convert() -> String { return String(data) }
}
其结果是,编译器现在抱怨TargetType
被重新定义.
This has the effect that the compiler now complains the the TargetType
was redefined.
我最后的尝试是定义两个协议,这些协议扩展Convertable
协议并约束TargetType
,然后通过扩展实现这两个协议:
My last try was to define two protocols that extend the Convertable
protocol and constrain the TargetType
and then implement both of them via extension:
protocol ConvertableString : Convertable {
associatedtype TargetType = String
}
protocol ConvertableInt : Convertable {
associatedtype TargetType = Int
}
extension MyData : ConvertableInt {
func convert() -> Int { return self.data }
}
extension MyData : ConvertableString {
func convert() -> String { return String(self.data) }
}
这现在使编译器对扩展感到满意,但不再对show
进行调用,因为它不知道可以使用MyData
来调用该函数.
Which now makes the compiler happy for the extensions but no longer for the call to show
because it doesn’t know that it can call the function with MyData
.
我有没有监督过的事情,或者目前无法迅速完成?
Is there some thing that I have overseen or is this currently not possible in swift?
推荐答案
我只是提供了一种存档方法.诀窍是在协议的子类型之一中添加另一个关联类型:
I just fund a way to archive this. The trick is to add another associated type in one of the subtypes of the protocol:
protocol ConvertableInt : Convertable {
associatedtype TResI
typealias TargetType = TResI
}
extension MyData : Convertable {
typealias TargetType = String
func convert() -> String { return String(self.data) }
}
extension MyData : ConvertableInt {
typealias TResI = Int
func convert() -> TResI { return self.data }
}
这也允许摆脱字符串的第二个子类型.
This also allows to get rid of the second subtype for string.
虽然这通过了编译器,但它在运行时完全崩溃了!
编译器始终调用在显式typealias
处定义的方法.在这种情况下:
The compiler always calls the method defined which was defined at the explicit typealias
. In this case:
typealias TargetType = String
这将导致将地址解释为整数,并给您完全错误的结果.如果您反过来定义它,它将简单地崩溃,因为它试图将整数解释为地址.
Which will result in interpreting the address as a integer and give you totally wrong results. If you define it vice versa it will simply crash because it tries to interpret the integer as a address.
这篇关于实施具有不同关联类型的协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!