实施具有不同关联类型的协议 [英] implement protocol with different associated type

查看:102
本文介绍了实施具有不同关联类型的协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个协议,我的快速代码库,我有一个具有关联类型和两种方法的协议.两种方法都为协议的关联类型定义了不同的通用约束.而且我想使该结构符合两种协议,但具有两种不同的关联类型.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆