假设我有一个 Animals 数组,我想将它转换为 Cats 数组。在这里,Animal 是 Cat 采用的协议(protocol)。我想要像 let cats: [Cat] = animals as 这样的东西! [Cat]
但此段在编译时出错(顺便说一句,我同时使用 Linux Swift 3 和 Mac Swift 2.2)。我的解决方法是创建一个单独向下转换每个项目并将其添加到新数组的函数(参见下面的小示例)。它产生了预期的结果,但没有我想要的那么干净。
我的问题是:
这完全是愚蠢的吗,我只是缺少一种更简单的方法来做到这一点?
如何在下面的函数中传递一个类型作为目标参数,而不是传递一个实例? (例如,我想传递 Cat.self 而不是 Cat(id:0),但这样做会导致错误提示无法将 Cat.Type 转换为预期的参数类型 Cat)
这是我目前所拥有的:
protocol Animal: CustomStringConvertible
{
var species: String {get set}
var id: Int {get set}
}
extension Animal
{
var description: String
{
return "\(self.species):\(self.id)"
}
}
class Cat: Animal
{
var species = "felis catus"
var id: Int
init(id: Int)
{
self.id = id
}
}
func convertArray<T, U>(_ array: [T], _ target: U) -> [U]
{
var newArray = [U]()
for element in array
{
guard let newElement = element as? U else
{
print("downcast failed!")
return []
}
newArray.append(newElement)
}
return newArray
}
let animals: [Animal] = [Cat(id:1),Cat(id:2),Cat(id:3)]
print(animals)
print(animals.dynamicType)
// ERROR: cannot convert value of type '[Animal]' to specified type '[Cat]'
// let cats: [Cat] = animals
// ERROR: seg fault
// let cats: [Cat] = animals as! [Cat]
let cats: [Cat] = convertArray(animals, Cat(id:0))
print(cats)
print(cats.dynamicType)
最佳答案
- Am I missing an easier way to do this?
您可以使用 map
进行转换:
let cats: [Cat] = animals.map { $0 as! Cat }
- how can I pass a type as the target parameter in the function below, rather than passing an instance?
首先,您需要删除实例参数:
func convertArray<T, U>(array: [T]) -> [U] {
var newArray = [U]()
for element in array {
guard let newElement = element as? U else {
print("downcast failed!")
return []
}
newArray.append(newElement)
}
return newArray
}
由于您不能显式指定类型参数,因此您需要向编译器提供一些信息来推断U
的类型。在这种情况下,您需要做的就是将结果分配给 Cat
数组:
let cats: [Cat] = convertArray(animals)
关于Swift:将对象数组转换为子类型数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37769858/