AnZ*_*AnZ 10 protocols swift encodable
我正在尝试通过符合Encodable协议的编码模型获取数据.但它无法encode像下面的代码那样调用func :
// MARK: - Demo2
class TestClass2: NSObject, Encodable {
var x = 1
var y = 2
}
var dataSource2: Encodable?
dataSource2 = TestClass2()
// error: `Cannot invoke 'encode' with an argument list of type '(Encodable)'`
let _ = try JSONEncoder().encode(dataSource2!)
//func encode<T>(_ value: T) throws -> Data where T : Encodable
Run Code Online (Sandbox Code Playgroud)
但在另一个演示中,它运作良好,为什么?
// MARK: - Demo1
protocol TestProtocol {
func test()
}
class TestClass1: NSObject, TestProtocol {
func test() {
print("1")
}
var x = 1
var y = 2
}
var dataSource1: TestProtocol?
dataSource1 = TestClass1()
func logItem(_ value: TestProtocol) {
value.test()
}
logItem(dataSource1!)
Run Code Online (Sandbox Code Playgroud)
SPa*_*tel 18
试试这个代码,它可以扩展编码
extension Encodable {
func toJSONData() -> Data? {
return try? JSONEncoder().encode(self)
}
}
Run Code Online (Sandbox Code Playgroud)
使用
protocol MyEncodable: Encodable {
func toJSONData() -> Data?
}
extension MyEncodable {
func toJSONData() -> Data?{
return try? JSONEncoder().encode(self)
}
}
Run Code Online (Sandbox Code Playgroud)
你不能传递协议,但你可以使用泛型来要求一个符合一个的类:
func printJSON<T: Encodable>(_ data: T) {
if let json = try? JSONEncoder().encode(data) {
if let str = String(data: json, encoding: .utf8) {
print(str)
}
}
}
// Now this should work
var dataSource2 = TestClass2()
printJSON(dataSource2!)
Run Code Online (Sandbox Code Playgroud)
有多种方法可以解决这个问题。
@SPatel 扩展解决方案Encodable是一种可能性。但是,我个人尽量避免使用扩展来污染 Apple 提供的协议。
如果我在字里行间阅读,看来您想要的是传递任何符合其他结构/类中Encodable的函数/方法的构造。
让我们举一个例子来说明我认为您正在努力实现的目标:
struct Transform {
static func toJson(encodable: Encodable) throws -> Data {
return try JSONEncoder().encode(encodable)
}
}
Run Code Online (Sandbox Code Playgroud)
但是,Xcode 会抱怨:
Protocol type 'Encodable' cannot conform to 'Encodable' because only concrete types can conform to protocols
Run Code Online (Sandbox Code Playgroud)
更 Swift 的解决方案是在函数上使用受约束的泛型:
struct Transform {
static func toJson<EncodableType: Encodable>(encodable: EncodableType) throws -> Data {
return try JSONEncoder().encode(encodable)
}
}
Run Code Online (Sandbox Code Playgroud)
现在编译器可以推断符合 的类型,Encodable我们可以按预期调用函数:
let dataSource = TestClass2()
let jsonData = try? Transform.toJson(encodable: dataSource)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3194 次 |
| 最近记录: |