假设我有一个动物数组,我想将其转换为猫的数组。这里,动物是猫采用的协议。我希望像
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)
map
中执行相同的操作。使用感叹号的as!
运算符也会在转换失败时抛出异常。 - Sergey Kalinichenko