【问题标题】:Downcasting Multidimensional Arrays Swift向下转换多维数组 Swift
【发布时间】:2014-07-22 06:55:57
【问题描述】:

我正在尝试在符合协议的类的子类中向下转换协议所需的多维数组属性。但是,目前编译器在我这样做时给了我一个错误。错误是:'DataClass' is not identical to 'Any'

奇怪的是,当属性简化为一维数组时,错误就消失了。这可能是 Swift 的一个错误,还是我不明白 Swift 如何处理多维数组的类型?

这自 Swift 1.0 以来一直存在,所以我觉得我在这里遗漏了一些明显的东西......

我已经在一个易于测试的代码 sn-p 中重现了我的情况:

protocol MyProtocol {    
    var myProperty: ([[Any]])! { get set }

    func myFuncReturn() -> Any
    func myFuncParam(param: Any)
}

class MyClass: MyProtocol {    
    var myProperty: ([[Any]])!

    init(myProperty: ([[Any]])!) {
        self.myProperty = myProperty
    }

    func myFuncReturn() -> Any {
        return myProperty[0][0]
    }

    func myFuncParam(param: Any) { }
}

class MySubclass: MyClass {

    var myPropertyOver: ([[DataClass]])! {
    return myProperty as? ([[DataClass]])
    }

    init() {
        super.init(myProperty: [[DataClass()]])
    }
}

class DataClass { }

感谢您的帮助!

【问题讨论】:

    标签: multidimensional-array swift protocols subclassing downcast


    【解决方案1】:

    问题仅仅在于您对应该发生的事情不够具体。假设你有一个数组数组,有些是 DataClass,有些不是。怎么办?您需要在代码中解释这一点。

    当您将[AnyObject] 转换为[Int] 时,这只是一种速记。真正发生的是 Swift 循环遍历整个数组并测试每个元素是否可以转换为 Int。

    但是想要做的事情是没有没有简写的事情。事实上,对我(因此对 Swift 而言)你做什么 想要做什么远非显而易见。你必须是明确的

    这样看。我们可以将整个示例简化为这个简单的案例:

    var arr = [[AnyObject]]()
    arr = [[1],[2]]
    var arr2 = [[AnyObject]]()
    arr2 = [[1],["howdy"]]
    

    现在我猜你想要的是:如果给定数组中的每个数组都是一个可以转换为[Int] 的数组,那就去做吧。如果不是,那么你应该以 nil 结束:尝试失败。

    好的,如果这是你想要的,那就是你必须做的。它没有神奇的速记。所以,例如:

    func cast(array:[[AnyObject]]) -> [[Int]]? {
        let result = array.map {
            (subarr:[AnyObject]) -> [Int]? in
            if let subarr = subarr as? [Int] {
                return subarr
            } else {
                return nil
            }
        }
        var foundnil = false
        for subarr in result {
            if subarr == nil {
                foundnil = true
                break
            }
        }
        if foundnil {
            return nil
        }
        return result.map{$0!}
    }
    

    这是它工作正常的证据:

    cast(arr) // [[1], [2]]
    cast(arr2) // nil
    

    如果我不明白您期望的输出,那么只需将 cast 函数更改为 get 您期望的输出。但这就是重点;根本不清楚你想要什么。你不能只是在这件事上投掷演员表并期望它是有意义的,或者让 Swift 读懂你的想法。你必须说你想说的。

    【讨论】:

    • 啊,当然,这很有意义。确实很明显,谢谢@matt
    猜你喜欢
    • 2022-11-27
    • 2021-05-11
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多