简体   繁体   中英

Cast value to array of unknown `Element` type

Assuming a function that operates on any Array :

func g<T>(array: [T]) -> Void {
  // ...
}

...and a function that receives a value of type Any :

func f(x: Any) -> Void {
  if x is Array {
    // g(?)
  }
}

How can I get a properly typed version of x that I can pass to g ?

Note that g doesn't rely (explicitly) on the type T . All it needs is the ability to iterate over the elements, which can be treated as values of type Any . Any solution that rewrites g to remove the type parameter is therefore also acceptable.

Edit : to make things harder, I'd like this to work on Linux, where Swift arrays aren't NSArray s until you've called .bridge() on them.

Warning Please note that the below results are based on my experiments on Mirror and work in Swift 2.1.1 (Xcode 7.1.1). It might be that future Swift versions will change the Mirror behaviour.

If finding out dynamically if the value is an array of any type, you could use Swift's reflection support, via the Mirror struct:

func processArray(array: Any) -> Bool {
    let mirror = Mirror(reflecting: array)
    guard mirror.displayStyle == .Collection else {
        return false
    }

    print("array has \(mirror.children.count) elements")

    return true
}

func f(x: Any) {
    if processArray(x) {
        // i just found an array
    }
}

f([1, 2, 3, "4"]) // prints "array has 4 elements"

if you want to keep the generic, you could do this instead:

func g<T>(array: [T]) -> Void {

}

func f(x: Any) -> Void {
    if let array = x as? [Any] {
        g(array)
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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