Ios 无法推断泛型参数-数组扩展名
我有一个通用方法来创建对象,该对象从响应扩展协议Ios 无法推断泛型参数-数组扩展名,ios,swift,Ios,Swift,我有一个通用方法来创建对象,该对象从响应扩展协议 extension FromResponse { static func object<T>(_ response: [String: Any]?) -> T? where T: FromResponse, T: NSObject { guard let response = response else { return nil } let obj: T = T() ret
extension FromResponse {
static func object<T>(_ response: [String: Any]?) -> T? where T: FromResponse, T: NSObject {
guard let response = response else { return nil }
let obj: T = T()
return obj
}
}
工作做得很好。但有时我会从响应中获取对象数组,因此我也希望使用通用解析器:
static func objects<T>(_ response: [[String: Any]]?) -> [T]? where T: FromResponse, T: NSObject {
guard let response = response else { return nil }
var returnArray: [T] = [T]()
for singleResponse in response {
if let object: T = T.object(singleResponse) {
returnArray.append(object)
}
}
return returnArray
}
它说:
无法推断泛型参数“T”
我知道这是什么意思,但我指定了类型,所以这个错误不应该发生。当我这样做时:
var typ: [MyObject] = [MyObject]()
for singleResponse in (response as? [[String: Any]])! {
let pack: MyObject? = MyObject.object(singleResponse)
typ.append(pack!)
}
它起作用了
为什么??如何让解析器返回泛型对象数组?我不知道为什么斯威夫特说“无法推断泛型参数‘t’”,但我猜这与数组协方差有关
协方差是什么?考虑这一点:
class Base { }
class Sub: Base { }
func f(_ array: [Base]) { }
能否将[Sub]
传递给f
?在斯威夫特,你可以。因为Sub
是Base
的子类型,[Sub]
是[Base]
的子类型。(这称为“协方差”),因此您可以将[Sub]
传递到允许[Base]
的任何位置:
f([Sub]())
// No errors.
您可以返回一个[Sub]
,其中需要一个[Base]
:
func g() -> [Base] { return [Sub]() }
// No errors.
您可以将[Sub]
分配给[Base]
变量:
let bases: [Base] = [Sub]()
// No errors.
回到你的代码:
static func objects<T>(_ response: [[String: Any]]?) -> [T]? ...
let myObjects: [MyObject]? = MyObject.objects(response)
不清楚为什么这个方法在MyObject
类上。也许您应该将其作为[[String:Any]]
上的一个方法:
extension Collection where Element == [String: Any] {
func objects<T>(ofType type: T.Type) -> [T]? ...
}
let myObjects = response.objects(ofType: MyObject.self)
扩展集合,其中元素==[String:Any]{
func对象(类型:T.type)->[T]。。。
}
让myObjects=response.objects(类型:MyObject.self)
我不知道为什么斯威夫特说“无法推断通用参数‘t’”,但我猜它与数组协方差有关
协方差是什么?考虑这一点:
class Base { }
class Sub: Base { }
func f(_ array: [Base]) { }
能否将[Sub]
传递给f
?在斯威夫特,你可以。因为Sub
是Base
的子类型,[Sub]
是[Base]
的子类型。(这称为“协方差”),因此您可以将[Sub]
传递到允许[Base]
的任何位置:
f([Sub]())
// No errors.
您可以返回一个[Sub]
,其中需要一个[Base]
:
func g() -> [Base] { return [Sub]() }
// No errors.
您可以将[Sub]
分配给[Base]
变量:
let bases: [Base] = [Sub]()
// No errors.
回到你的代码:
static func objects<T>(_ response: [[String: Any]]?) -> [T]? ...
let myObjects: [MyObject]? = MyObject.objects(response)
不清楚为什么这个方法在MyObject
类上。也许您应该将其作为[[String:Any]]
上的一个方法:
extension Collection where Element == [String: Any] {
func objects<T>(ofType type: T.Type) -> [T]? ...
}
let myObjects = response.objects(ofType: MyObject.self)
扩展集合,其中元素==[String:Any]{
func对象(类型:T.type)->[T]。。。
}
让myObjects=response.objects(类型:MyObject.self)
您能否向我们展示MyObject
的声明(以及作为参数传递的响应
)?我无法重现你的问题。尽管通过让方法分别返回Self?
和[Self]?
可以完全避免这种类型推断的需要(如果需要,可以使用where Self:NSObject
约束扩展)。你甚至可能想考虑制作<代码>对象(“:”)< /Cord>初始化器。原来这是一个XCODE奇怪的行为,在退出和清除DD后编译…感谢您的评论,您无法重现问题。这就是我要做的。你能给我们看一下MyObject
的声明(以及作为参数传递的响应
)吗?我无法重现你的问题。尽管通过让方法分别返回Self?
和[Self]?
可以完全避免这种类型推断的需要(如果需要,可以使用where Self:NSObject
约束扩展)。你甚至可能想考虑制作<代码>对象(“:”)< /Cord>初始化器。原来这是一个XCODE奇怪的行为,在退出和清除DD后编译…感谢您的评论,您无法重现问题。这让我这么做