Swift 4使用Codable遇‘Generic parameter 'T' could not be inferred’错误求助
问题:JSONEncoder.encode时出现“Generic parameter 'T' could not be inferred”错误
我在执行Swift代码时,在let data = try encoder.encode(obj)这一行遇到了“Generic parameter 'T' could not be inferred”错误,以下是我的代码:
import Foundation struct User: Codable { var firstName: String var lastName: String } let u1 = User(firstName: "Ann", lastName: "A") let u2 = User(firstName: "Ben", lastName: "B") let u3 = User(firstName: "Charlie", lastName: "C") let u4 = User(firstName: "David", lastName: "D") let a = [u1, u2, u3, u4] var ret = [[String: Any]]() for i in 0..<a.count { let param = [ "a" : a[i], "b" : 45 ] as [String : Any] ret.append(param) } let obj = ["obj": ret] let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted let data = try encoder.encode(obj) // This line produces an error print(String(data: data, encoding: .utf8)!)
请问我哪里出错了?
回答
嘿,这个问题的核心原因很明确:JSONEncoder只能编码符合Codable协议的类型,但你创建的obj里包含了Any类型的元素,而Any并不遵循Codable。
你看,你的ret是[[String: Any]]类型,里面每个字典里的"a"对应User(虽然User是Codable),但"b"是Int,整体字典被声明为[String: Any],这就导致整个obj的类型变成了[String: [[String: Any]]]——而Any无法被JSONEncoder处理,编译器也就没法推断出encode(_:)方法需要的泛型参数T,所以报错了。
解决办法也很简单:别用Any类型的字典,而是创建对应的Codable结构体来匹配你的数据结构。这样JSONEncoder就能明确知道要编码的类型了。
修改后的代码如下:
import Foundation struct User: Codable { var firstName: String var lastName: String } // 新增结构体表示单个param的结构 struct Param: Codable { let a: User let b: Int } // 新增结构体表示最外层的obj结构 struct RootObject: Codable { let obj: [Param] } let u1 = User(firstName: "Ann", lastName: "A") let u2 = User(firstName: "Ben", lastName: "B") let u3 = User(firstName: "Charlie", lastName: "C") let u4 = User(firstName: "David", lastName: "D") let a = [u1, u2, u3, u4] // 用Param结构体生成数组,替代Any类型字典 let ret = a.map { Param(a: $0, b: 45) } let obj = RootObject(obj: ret) let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted do { let data = try encoder.encode(obj) if let jsonString = String(data: data, encoding: .utf8) { print(jsonString) } } catch { print("编码错误:\(error)") }
这样修改后,所有类型都明确遵循Codable协议,编译器能准确推断泛型参数,编码就能正常工作了。另外我还把try放到了do-catch块里,这是更规范的错误处理方式哦。
内容的提问来源于stack exchange,提问作者user1107173
相关产品推荐
相关产品推荐

