类型 'JSONEncoder' 的默认参数值无法转换为类型 'Encoder' (TopLevelEncoder)

Default argument value of type 'JSONEncoder' cannot be converted to type 'Encoder' (TopLevelEncoder)

我试图制作一个通用方法,该方法采用 TopLevelEncoderTopLevelDecoder 以使其可注入(例如,生产代码中的 JSONEncoderCustomEncoder 用于检测)。因为这两个协议都有关联类型,所以我限制了它们的类型,而不是仅仅做 encoder: TopLevelEncoder = JSONEncoder()。我想出了这个方法:

func test<Encoder, Decoder>(
    encoder: Encoder = JSONEncoder(),
    decoder: Decoder = JSONDecoder()
) where Encoder: TopLevelEncoder, Decoder: TopLevelDecoder {
    //encode and decode
}

编译器给我以下错误信息:Default argument value of type 'JSONEncoder' cannot be converted to type 'Encoder'。我不明白它怎么不能转换为类型 Encoder 因为 JSONEncoder 继承自 TopLevelEncoder.

我可能误解了泛型和 associatedType 的工作原理,但我也无法理解这条错误消息。有人可以帮我吗?

我看到了解决这个问题的其他方法,比如创建一个像 AnyEncoder 这样的新协议并用它扩展 JSONEncoder。但在我看来,使用现有协议会更干净。另外我的方法需要一个 TopLevelDecoder 因为我使用的是 URLSessionss .dataTaskPublisher (.decode(...)).

我不知道在这种情况下强制转换有多安全,但这似乎可以编译并工作:

struct User: Codable {
    var name: String
}

func decodeEncode<Encoder, Decoder>(
  encoder: Encoder = JSONEncoder() as! Encoder, 
  decoder: Decoder = JSONDecoder() as! Decoder) 
  where Encoder: TopLevelEncoder, Decoder: TopLevelDecoder, 
        Encoder.Output == Data, Decoder.Input == Data
{
    let bruceData = try! encoder.encode(User(name: "Bruce Lee"))
    let bruce = try! decoder.decode(User.self, from: bruceData)

    print("bruce: \(bruce)")
}

decodeEncode(encoder: JSONEncoder(), decoder: JSONDecoder())

可以限制 Encoder.Output == Decoder.Input 但我明确指定了 Data 因为 JSONEncoderJSONDecoder 都适用于 Data.