Why doesn’t Swift call my overloaded method with a more specific type?

后端 未结 5 444
有刺的猬
有刺的猬 2021-01-02 15:38

I use Decodable to decode a simple struct from JSON. This works by conforming to a Decodable protocol:

extension BackendServerID: Decodable {

          


        
5条回答
  •  攒了一身酷
    2021-01-02 16:12

    Let's consider the minimal example:

    protocol Decodable {
        static func decode(_ json: Any) throws -> Self
    }
    
    struct BackendServerID {
    }
    
    extension Decodable {
        static func decode(_ string: String) throws -> Self {
            return try decode(string)
        }
    }
    
    extension BackendServerID : Decodable {
        static func decode(_ json: Any) throws -> BackendServerID {
            return BackendServerID()
        }
    }
    

    The implementation of decode in BackendServerId replaces the default implementation of Decodable.decode (the parameters are covariant, similar case as overriding). Your use case would work only if both functions were declared on the same level, e.g.:

    extension BackendServerID : Decodable {
        static func decode(_ json: Any) throws -> BackendServerID {
            return BackendServerID()
        }
    
        static func decode(_ string: String) throws -> Self {
            return try decode(string as Any)
        }
    }
    

    Also note the as Any which is necessary to prevent recursion.

    To prevent confusion, you should name functions that accept string and Any differently, e.g decode(string:) and decode(json:).

提交回复
热议问题