[英]Generics and Constraints (`Instance method '…' requires that 'T' conform to 'Decodable'`)
我有一個通用結構,允許使用不同的類型。 我不想將整個結構限制為僅可解碼項目。
修復以下錯誤的最佳方法是什么,我嘗試僅在 T 符合 Decodable 時執行一些代碼: Instance method '...' requires that 'T' conform to 'Decodable'
struct Something<T> {
...
func item<T>(from data: Data) -> T? where T: Decodable {
try? JSONDecoder().decode(T.self, from: data)
}
func getter() -> T {
let value = ...
if let value = value as? T { return value } // something simple like string
if let data = value as? Data, T.self is Decodable { // something complex
return item(from: data) ?? defaultValue // error is thrown here
}
return defaultValue
}
}
如您所見,我正在檢查是否符合 if 子句,但這還不足以訪問受約束的方法嗎? :/
對我來說,T 只需要在某些部分符合Decodable
而不是其他部分,這對我來說毫無意義。 我會將結構重寫為
struct Something<T: Decodable> {
func item(from data: Data) -> T? {
try? JSONDecoder().decode(T.self, from: data)
}
func getter() -> T {
let value = ...
if let data = value as? Data
return item(from: data) ?? defaultvalue
}
return defaultvalue
}
}
首先,您應該在定義結構時將 T 限制為 Decodable 。 其次,您不能在內部將 T 定義為函數的通用參數,因為它不會被編譯器視為結構符合的相同 T。 相反,它將被視為一個新的和不同的泛型類型約束(您只是碰巧給出了相同的名稱)。 這樣做就足夠了:
struct Something<T: Decodable> {
var defaultValue: T
var data: Data
func item(from data: Data) -> T? {
try? JSONDecoder().decode(T.self, from: data)
}
func getter() -> T {
item(from: data) ?? defaultValue
}
}
您可以使用擴展來定義更受約束的方法:
struct Something<T> {
var defaultValue: T
func getter() -> T {
return defaultValue
}
}
extension Something where T: Decodable {
func getter() -> T {
// I'm assuming here that you have a property data: Data
try? JSONDecoder().decode(T.self, from: data) ?? defaultValue
}
}
目前還不完全清楚您將如何以有意義的方式使用這種類型。 您的代碼的構造方式, value
是Any
類型。 這是你的意思嗎? (我猜,不是)
在某個地方,您需要制作Something
的具體版本——即它會是Something<Int>
或Something<String>
或Something<SomeDecodableType>
——此時T
將是那個具體的類型,正如你所看到的,有T
的各種版本之間沒有任何共同點,除了Any
。
所以弄清楚Something
的哪些部分真正是共同的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.