简体   繁体   English

Swift:在协议一致性中覆盖协议扩展中的associatedtype

[英]Swift: override associatedtype from protocol extension in protocol conformance

So, I'm trying to achieve this: 因此,我正在努力实现这一目标:

Have a protocol with associatedtype who will handle json parsing into his extension. 有一个带有associatedtype的协议,该协议将处理json解析为其扩展名。 The associatedtype must conform to Decodable : Decodable必须符合Decodable

protocol MyProtocol {
  associatedtype ResponseType: Decodable
  func handleResponse(data: Data) -> ResponseType
}

What I'm want to do is to set a default type for responseType into my extension and then, if needed, override that type into the class, or struct conformance. 我想要做的是将responseType的默认类型设置为扩展名,然后,如果需要,将该类型重写为类或struct一致性。 Something like this. 这样的事情。

extension MyProtocol {
  typealias ResponseType = MyDefaultDecodableType

  func handleResponse(data: Data) -> ResponseType { ... }
}

class MyObject: MyProtocol {
  typealias ResponseType = AnotherDecodableType
}

Problem is I'm getting an error like this inside MyObject : 问题是我在MyObject遇到这样的错误:

error: type 'MyObject' does not conform to protocol 'MyProtocol'
class MyObject: MyProtocol {
      ^
note: multiple matching types named 'ResponseType'
    associatedtype ResponseType: Decodable
                   ^
note: possibly intended match
  typealias ResponseType = AnotherDecodableType
            ^
note: possibly intended match
    public typealias ResponseType = MyDefaultDecodableType

I don't know if it's possible to achieve what I'm trying or I'm approaching the wrong way. 我不知道是否有可能实现我正在尝试的目标,或者我正在采取错误的方法。 Anyone can give me some light? 有人可以给我一点光吗?

Thanks. 谢谢。

I have created the same code. 我已经创建了相同的代码。 There are some facts that need to be understood here. 这里有一些事实需要理解。

extension MyProtocol {
    typealias ResponseType = MyDefaultDecodableType

    func handleResponse(data: Data) -> ResponseType {

        return try! JSONDecoder().decode(MyDefaultDecodableType.self, from: data)

    }
}

Conceptually, there are no generic protocols in Swift. 从概念上讲,Swift中没有通用协议。 But by using typealias we can declare a required alias for another type. 但是通过使用typealias我们可以为另一种类型声明必需的别名。

Your extension doesn't need to define typealias ResponseType = MyDefaultDecodableType as it is going to provide some default implementation using MyDefaultDecodableType , so it is useless. 您的扩展不需要定义类型typealias ResponseType = MyDefaultDecodableType因为它将使用MyDefaultDecodableType提供一些默认实现,因此它没有用。

So your extension would be something like this 所以您的扩展名将是这样的

extension MyProtocol {
  //  typealias ResponseType = MyDefaultDecodableType // NO NEED FOR IT

    func handleResponse(data: Data) -> MyDefaultDecodableType {
        print("Test \(self)")
        return try! JSONDecoder().decode(MyDefaultDecodableType.self, from: data)

    }
}

Now you can define 现在您可以定义

class MyObject:MyProtocol {
    typealias ResponseType = AnotherDecodableType

    func handleResponse(data: Data) -> ResponseType {
        print("Test \(self)")

        return try! JSONDecoder().decode(AnotherDecodableType.self, from: data)

    }

}
class MyObject2:MyProtocol {


}

Without any errors 没有任何错误

Now if you use 现在,如果您使用

MyObject().handleResponse(data:data)
MyObject2().handleResponse(data:data2)

You will get 你会得到

test __lldb_expr_44.MyObject 测试__lldb_expr_44.MyObject

test __lldb_expr_44.MyObject2 测试__lldb_expr_44.MyObject2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM