我正试图向下cast一个多维数组属性,这是协议符合类的子类中协议所要求的。然而,目前编译器给我一个错误,当我这样做。错误为:'DataClass' is not identical to 'Any'
。
奇怪的是,当属性被简化为单维数组时,错误就消失了。这可能是一个错误与Swift或我不理解Swift如何处理多维数组的类型?
这在Swift 1.0就已经存在了,所以我觉得我在这里错过了一些明显的东西…
我在一个容易测试的代码片段中重现了我的情况:
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 { }
谢谢你的帮助!
问题仅仅是你没有足够具体地说明应该发生什么。假设你有一个数组的数组有些是DataClass的,有些不是。现在怎么办呢?你需要在你的代码中解释。
当您将[AnyObject]
转换为[Int]
时,这只是一种简写。真正发生的是,Swift循环遍历整个数组,并测试每个every元素是否可以被强制转换为Int类型。
但是你想要做的事情是没有简写的。事实上,对于我(以及Swift)来说,你做什么想做什么并不明显。你必须显式
这样看。我们可以把整个例子简化成这个简单的例子:
var arr = [[AnyObject]]()
arr = [[1],[2]]
var arr2 = [[AnyObject]]()
arr2 = [[1],["howdy"]]
现在我猜你想要的是这样的:如果给定数组中的每个数组都是一个可以转换为[Int]
的数组,那么就这样做。如果不是,那么你应该以nil结束:the attempt failed.
好,如果这是你想要的,那你就得做。没有神奇的速记法。例如:
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
函数更改为即可获得您期望的输出。但这就是重点;你想要什么一点也不清楚。你不能只是在这个东西上投一个cast,然后期望它是有意义的,或者让Swift读懂你的想法。