微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我有一系列动物,我想将它投射到一系列的猫.在这里,Animal是Cat采用的协议.我喜欢让猫吃的东西:[猫] =动物! [Cat]但这个seg在编译时出错(顺便说一句,我在 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)

解决方法

  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)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐