简体   繁体   English

向下转换多维数组Swift

[英]Downcasting Multidimensional Arrays Swift

I am trying to downcast a multidimensional array property which is required by a protocol in a subclass of the protocol conforming class. 我试图在协议一致类的子类中向下转换协议要求的多维数组属性。 However currently the compiler is giving me a an error when I do so. 但是目前,编译器在执行此操作时给我一个错误。 The error is: 'DataClass' is not identical to 'Any' . 错误是: 'DataClass' is not identical to 'Any'

The strange thing is that when the property is reduced to a single dimensional array the error disappears. 奇怪的是,当属性简化为一维数组时,错误消失了。 Could this be a bug with Swift or am I not understanding how Swift handles the typing of multidimensional arrays? 这可能是Swift的错误,还是我不了解Swift如何处理多维数组的类型?

This has been around since Swift 1.0, so I feel like I am missing something obvious here... 自Swift 1.0起就存在这种情况,所以我觉得这里缺少明显的东西...

I have reproduced my situation in an easily testable code snippet: 我在一个易于测试的代码片段中再现了我的情况:

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 { }

Thanks for your help! 谢谢你的帮助!

The problem is merely that you aren't being specific enough about what should happen. 问题仅仅是您对应该发生的事情不够具体。 Let's say you've got an array of arrays and some are of DataClass and some are not. 假设您有一个数组数组,有些是DataClass,有些不是。 Now what? 怎么办? You need to explain that in your code. 您需要在代码中进行解释。

When you cast, say, an [AnyObject] to [Int] , that is just a shorthand. 当您将[AnyObject][Int] ,这只是简写。 What really happens is that Swift cycles through the whole array and tests whether each every element can be cast to an Int. 真正发生的是Swift遍历整个数组并测试是否每个元素都可以转换为Int。

But the thing you want to do is something for which there is no shorthand. 但是想要做的事情是没有速记的。 Indeed, it is far from obvious to me (and therefore to Swift) what you do want to do. 确实,对我(因此对Swift)而言,您要做的事情远非显而易见。 You have to be explicit . 你必须明确

Look at it this way. 这样看。 We can reduce the entire example to this simple case: 我们可以将整个示例简化为以下简单情况:

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

Now I am guessing that what you want is this: If every array in the given array is an array that can be cast down to [Int] , do it. 现在,我猜想您想要的是:如果给定数组中的每个数组都是可以转换为[Int]的数组,请执行此操作。 If not, then you should end up with nil: the attempt failed. 如果不是,那么您应该以nil结尾:尝试失败。

Okay, so if that's what you want, that's what you have to do . 好的,如果这就是您想要的,那就是您必须要做的 There is no magic shorthand for it. 没有魔术的捷径。 So, for example: 因此,例如:

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!}
}

And here's proof that it's working properly: 这证明它可以正常工作:

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

If I haven't understood what output you expect, then just change the cast function to get the output you expect. 如果我不了解您期望的输出,则只需更改cast函数即可获得您期望的输出。 But that's the whole point; 但这就是重点。 it is not at all clear what you want. 不清楚您想要什么。 You cannot just throw a cast at this thing and expect that to be meaningful, or for Swift to read your mind. 您不能仅仅对这种事情投以期望并使其有意义,或者让Swift读懂您的想法。 You must say what you want. 你必须说你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM