2017-10-14 104 views
-1

下面的代碼無法編譯:斯威夫特4 JSONDecoder解碼協議類型

public protocol Foo: Decodable { 
    var message: String { get } 
} 
struct Bar: Foo { 
    let message: String 
} 

// the type conforming Foo protocol is passed from somewhere 
let type: Foo.Type = Bar.self 
decode(type: type, from: Data()) 

func decode<T>(type: T.Type, from data: Data) Where T: Decodable { 
    let decoder = JSONDecoder() 
    try! decoder.decode(type, from: data) 
} 

它拋出的錯誤: Cannot invoke 'decode' with an argument list of type '(Foo.Type, from: Data)'

。你們有什麼想法?

+0

我需要約束的參數到這樣的協議:'func decode (type:T,from data:Data){讓解碼器= JSONDecoder() 試試! decode.decode(類型,來自:data) }' – 3stud1ant3

+0

@ 3stud1ant3'decode(type:Bar.self,from:data)'throws'無法用類型爲'(T,from:Data)的參數列表調用'decode' )'' – akabc

+0

'JSONEncoder' /'JSONDecoder'預計具體的類型,你不能使用協議類型。 – vadian

回答

1

你可以使用這樣的:

public protocol Foo: Decodable { 
    var message: String { get } 
} 
struct Bar: Foo { 
    let message: String 
} 

class ViewController: UIViewController { 
    let bar = """ 
     {"message": "Sample message"} 
    """ 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     let type = Bar.self 
     decode(type: type, from: bar.data(using: .utf8)!) 
    } 

    func decode<Foo>(type: Foo.Type, from data: Data) where Foo: Decodable { 
     let decoder = JSONDecoder() 
     let parsedData = try! decoder.decode(type, from: data) 
     print(parsedData) 
    } 
} 
+0

如何編譯? '''let type:Foo.Type = Bar.self decode(type:type,from:bar.data(using:.utf8)!)''',這是因爲** type **是從某處傳遞過來的,具體類型是未知的,我知道它唯一符合'Foo' – akabc

+0

你有什麼問題嗎? –

1

你應該在你的Bar使用Codable此相反:

protocol Foo { 
    var message: String { get } 
} 
struct Bar: Foo, Codable { 
    let message: String 
} 

用法:

let bar = Bar(message: "Just a message") 
if let data = try? JSONEncoder().encode(bar) { 
    print(String(data:data, encoding:.utf8) ?? "") // {"message":"Just a message"}\n"// lets decode it 
    if let decodedBar = try? JSONDecoder().decode(Bar.self, from: data) { 
     print(decodedBar.message) //"Just a message\n" 
    } 
} 
+0

我想解碼(類型)的參數從某處傳遞 – akabc

+0

你爲什麼要這麼做?只要使用使用代碼,無論你想解碼。 –

+0

我想'Bar.self'可以傳遞給這個函數'func decode(type:Foo.Type,from data:Data)' – akabc