Swift 向阵列投射任何

Swift 向阵列投射任何,swift,Swift,这是我试图使之生效的代码 struct A { var x:Int = 0 } struct B { var y:Int = 0 } var c: [String:Any] = [ "a":[A()], "b":[B()] ] for (key, value) in c { let arr = value as! [Any] } 它只是抛出异常。尝试将任何强制转换为[任何]时引发运行时异常 我想实现的主要功能是遍历任意数组(如果有)的元素。对我来说

这是我试图使之生效的代码

struct A {
    var x:Int = 0
}

struct B {
    var y:Int = 0
}

var c: [String:Any] = [
    "a":[A()],
    "b":[B()]
]

for (key, value) in c {
    let arr = value as! [Any]
}
它只是抛出异常。尝试将任何强制转换为[任何]时引发运行时异常

我想实现的主要功能是遍历任意数组(如果有)的元素。对我来说,向[任何]投任何球是很自然的,但出于某种原因,它不起作用。那个么,在swift中,我怎样才能做到这一点呢


我看到了一些将任意值强制转换为[A]或[B]的变通方法,但我的情况不是这样,因为数组可以只包含任意结构。

您可以使用运行时内省来检查字典中的值是否属于集合类型,如果是,则迭代它们的子元素=元素,对于数组大小写,并将它们附加到一个实际的Any数组中,让Swift知道字典中的一些值实际上是数组

例如如下

/* runtime introspection to extract array values from dictionary */
var commonAnyArr: [[Any]] = []
for (_, value) in c {
    if case let m = Mirror(reflecting: value)
        where (m.displayStyle ?? .Struct) == .Collection {
        let arr = m.children.map { $0.value }
        commonAnyArr.append(arr)
    }
}

/* resulting array of any arrs, that Swift now recognize as actual arrays */
commonAnyArr.forEach { print($0) }
/* [B(y: 3)]
   [A(x: 1), A(x: 2)] */

commonAnyArr.flatten().forEach { print($0) }
/* B(y: 3)
   A(x: 1)
   A(x: 2) */
或者,使用运行时自省来构造一个新字典,只包含c的键值对,其中由Any值包装的基础值实际上是一个数组,但是在新字典中为swift显式指定值是Any的数组


请注意,在Swift看来,上面的内容可能有点骇人听闻,它以静态类型和运行时安全性为傲,而且可能更有趣,更多的是出于技术方面,而不是用于实际的生产代码中。我个人绝不允许在我自己的生产中使用上面的内容。也许,如果您退一步,看看您是如何解决这个问题的,您可以重新设计代码和设计,以避免出现需要求助于运行时黑客的情况。

我真的很想看看您尝试这样做时的数据结构是什么样子的。这听起来有点像一个。啊,谢谢,这很有效!我遗漏的一点是,如果有数组,那么镜像的子元素就是它的元素。@user1682175乐意帮助。请注意我答案底部的免责声明,以及nhgrif:s对您的问题的评论,即,如果在解决您在本问题中提出的问题之前使用不同的方法,则上述解决方案可能完全可以避免。快乐编码!我的应用程序中有一个struct of structs等。我需要做的就是以一种好看的json方式将其打印到控制台中。这就是我遇到这个问题的地方。
/* runtime introspection to extract array values from dictionary */
var commonAnyArr: [[Any]] = []
for (_, value) in c {
    if case let m = Mirror(reflecting: value)
        where (m.displayStyle ?? .Struct) == .Collection {
        let arr = m.children.map { $0.value }
        commonAnyArr.append(arr)
    }
}

/* resulting array of any arrs, that Swift now recognize as actual arrays */
commonAnyArr.forEach { print($0) }
/* [B(y: 3)]
   [A(x: 1), A(x: 2)] */

commonAnyArr.flatten().forEach { print($0) }
/* B(y: 3)
   A(x: 1)
   A(x: 2) */
/* runtime introspection to extract array values from dictionary */
var dictOfAnyArrs: [String: [Any]] = [:]
for (key, value) in c {
    if case let m = Mirror(reflecting: value)
        where (m.displayStyle ?? .Struct) == .Collection {
        let arr = m.children.map { $0.value }
        dictOfAnyArrs[key] = arr
    }
}

/* "remaining" dictionary keys now only with [Arr] values */
for (key, arr) in dictOfAnyArrs {
    for element in arr {
        print("Do something with element \(element)")
    }
    print("---")
}
/* Do something with element B(y: 3)
   ---
   Do something with element A(x: 1)
   Do something with element A(x: 2)
   ---                                */