我有一个AnyObject
数组,我想把它(或其对象的一个)转换为通用类型T
,它可能是也可能不是一个数组。
我的第一次尝试:
class MyClass<T> {
func someMethod() -> T? {
let anyObjectArray: [AnyObject] = // ... array obtained from Objective-C framework
if let objectsAsCollection = anyObjectArray as? T { // Cast always fails
return objectsAsCollection
} else if let firstObject = anyObjectArray.first as? T {
return firstObject
} else {
return nil
}
}
}
当if let
为T
(例如Array
)时,第一次T.self == Array<SomeObject>.self
投射会失败。
我会尝试这样的事情,但它涉及以某种方式引入另一个泛型参数,因此无效如下所示:
extension MyClass where T == Array<U> {
fun someMethod() -> T? {
let anyObjectArray: [AnyObject] = // ... array obtained from Objective-C framework
if let objectsAsCollection = anyObjectArray.flatMap({ $0 as? U }) {
return objectsAsCollection
} else if let firstObject = anyObjectArray.first as? T {
return firstObject
} else {
return nil
}
}
}
想要这样做的原因是我使用Objective-C框架(RestKit)从REST API获取结果。我正在Swift中构建一个顶层,它根据所做的请求将这些结果作为特定类型传回,所以我有Result
类型看起来像这样:
enum Result<T>: {
case Success(T)
case Failure(Error)
}
有时候T
是一个单独的对象,有时它是一个对象数组,但Objective-C框架总是将结果作为数组返回。
答案 0 :(得分:3)
以下语法将起作用:
class MyClass<T> {
func someMethod() -> T? {
// let's not convert to [AnyObject] here, keep it as NSArray
let anyObjectArray: NSArray = ...
// For some reason conversion from [AnyObject] to [T] fails...
// However, conversion from NSArray is special
if let objectsAsCollection = anyObjectArray as? T {
return objectsAsCollection
} else if let firstObject = (anyObjectArray as [AnyObject]).first as? T {
return firstObject
} else {
return nil
}
}
}
但是,这只是一个可能的错误的解决方法。我们可以将问题归结为以下几点:
class GenericClass<T> {
func someMethod() {
let anyObjectArray: [AnyObject] = ["test1", "test2", "test3"]
print(T) //Array<String>
print(T.self == Array<String>.self) //true
print(anyObjectArray is [String]) //true
print(anyObjectArray is T) //false - BUG
}
}
let instance = GenericClass<[String]>()
instance.someMethod()
(报告:SR-1054)
对我来说这看起来像一个明显的错误。它实际上看起来像Type of optionals cannot be inferred correctly in swift 2.2
中讨论的bug的另一个实例