对"可编码"协议进行编码的泛型方法


import Foundation
protocol ProtocolA: Codable {
var var1: String { get }
}
struct Type1: ProtocolA {
var var1: String
var var2: Int
}
struct Type2: ProtocolA {
var var1: String
var var2: Bool
}
func encode<T: ProtocolA & Encodable>(object: T) throws -> Data {
return try JSONEncoder().encode(object as! T.Type)
}

将以上内容放在操场上会导致error: argument type 'T.Type' does not conform to expected type 'Encodable'

当我说T必须符合Encodable时,为什么会发生这种情况?

return try JSONEncoder().encode(object as! T.Type)

这意味着将object转换为T元类型。类型的类型。例如,1是Int。但"Int"本身有一个类型,即Int.Type,这是一个元类型。元类型不符合Encodable。

你的意思是:

return try JSONEncoder().encode(object as! T)

但你的意思是:

return try JSONEncoder().encode(object)

因为CCD_ 7总是T类型的。这是函数签名的显式类型。由于这个算法也不依赖ProtocolA,所以这一切都归结为:

func encode<T: Encodable>(object: T) throws -> Data {
return try JSONEncoder().encode(object)
}

您的编译器实际上在抱怨您在末尾所做的类型转换,即将object转换为T的metatype,在您的示例中为Type1.TypeType2.Type

从编码的角度来看,编译器需要知道的是模型对Encodable的确认,这在T: Codable语句中是隐含的。

import Foundation
protocol ProtocolA: Codable {
var var1: String { get }
}
struct Type1: ProtocolA {
var var1: String
var var2: Int
}
struct Type2: ProtocolA {
var var1: String
var var2: Bool
}
func encode<T: Codable>(object: T) throws -> Data {
return try JSONEncoder().encode(object)
}
let type2 = Type2(var1: "test1", var2: true)
print(type2)

最新更新