Swift:将对象数组转换为子类型数组

标签 swift

假设我有一个 Animals 数组,我想将它转换为 Cats 数组。在这里,Animal 是 Cat 采用的协议(protocol)。我想要像 let cats: [Cat] = animals as 这样的东西! [Cat] 但此段在编译时出错(顺便说一句,我同时使用 Linux Swift 3 和 Mac Swift 2.2)。我的解决方法是创建一个单独向下转换每个项目并将其添加到新数组的函数(参见下面的小示例)。它产生了预期的结果,但没有我想要的那么干净。

我的问题是:

  1. 这完全是愚蠢的吗,我只是缺少一种更简单的方法来做到这一点?

  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)

最佳答案

  1. Am I missing an easier way to do this?

您可以使用 map 进行转换:

let cats: [Cat] = animals.map { $0 as! Cat }
  1. 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/

相关文章:

ios - 核心数据 : app crashed when accesing to NSManagedObject attribute

ios - Swift 中的开关 - 开关中的 Case 标签应该至少有一个可执行语句

ios - 为什么 UILongPressGestureRecognizer 在 iOS 模拟器中工作但不适用于 iPhone

ios - 存储大图像以进行 map 叠加

ios - 仅当使用 RxBluetoothKit 连接成功时才延长蓝牙连接超时

objective-c - 如何在 Mac 上以编程方式访问文件信息?

ios - ContentInset 在 popViewController 之后自动改变

swift - 为什么 NSNotification 工作缓慢?

ios - 如何使收藏 View 倒置?

ios - SwipeCellKit 不滑动