Array< Any>上的快速模式匹配 [英] Swift Pattern match on Array<Any>

查看:119
本文介绍了Array< Any>上的快速模式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

雨燕1.2
我正在尝试在一个以类型为Any作为参数的函数的开关案例中进行模式匹配,以便分派给更专用的私有初始化.

Swift 1.2
I'm trying to pattern match in a switch case in a function that take a type Any as it's parameter, in order to dispatch to a private more specialize init.

这是一个游乐场推断:

import Foundation

struct myStruct {
}

func switchOnAny(any: Any) -> String {
    println("Dynamic Type == \(any.dynamicType)")
    switch any {
    case let array as [Any]:
        return "Array"
    case let array as NSArray:
        return "NSArray"
    default:
        return "Default"
    }
}

let emptyStringArray : [String] = []
let stringArray : [String] = ["Bob", "Roger"]
let intArray = [1, 2, 3]
let customStructArray : [myStruct] = []

println("\t\touput : \(switchOnAny([]))")
println("\t\touput : \(switchOnAny(emptyStringArray))")
println("\t\touput : \(switchOnAny(stringArray))")
println("\t\touput : \(switchOnAny(intArray))")
println("\t\touput : \(switchOnAny(customStructArray))")

会产生以下输出:

动态类型== __NSArrayI
输出:NSArray
动态类型== Swift.Array
输出:NSArray
动态类型== Swift.Array
输出:NSArray
动态类型== Swift.Array
输出:NSArray
动态类型== Swift.Array< __ lldb_expr_37.myStruct>
输出:默认

Dynamic Type == __NSArrayI
ouput : NSArray
Dynamic Type == Swift.Array
ouput : NSArray
Dynamic Type == Swift.Array
ouput : NSArray
Dynamic Type == Swift.Array
ouput : NSArray
Dynamic Type == Swift.Array<__lldb_expr_37.myStruct>
ouput : Default

我想知道为什么as [Any]案件没有得到,因为我从不要求NSArray?

I am wondering why the case as [Any] don't gets it since I'm never requesting an NSArray?

我可以假设任何类型的Swift数组都会进入NSArray案例,或者我需要写2个case语句(一个用于NSArray,一个用于[Any])以掩盖我的背(显然会有有需要)吗?

And can I assume that any kind of Swift array will get in the NSArray case or will I need to write 2 case statement (one for NSArray and one for [Any]) in order to cover my back (apparently there will be a need)?

进行更多测试后,我可以看到当我提供自定义结构的数组时,所有模式都将不匹配.我需要像[myStruct]这样的匹配项才能识别它.这正是我要避免的事情,因为这只是我可以接受的选择之一.

After making some more test, I can see that when I'm providing an array of a custom struct none of the pattern will match. I will need to have a match like [myStruct] for it to recognize. Which is exactly what I'm trying to avoid, because it is only one of the option that I can receive.

要提供更多上下文,我已将项目放在Github上: https://github.com/VinceBurn/SwiftyPlist/tree/test/init-Any . 该项目是关于TDD的,并且将属性列表表示为可通过下标访问的类似Struct的树. (如SwiftyJSON)

To give more context I've put my project on Github : https://github.com/VinceBurn/SwiftyPlist/tree/test/init-Any. The project is about TDD and representing a Property list as a Struct like tree that can be accessed by subscript. (like SwiftyJSON)

推荐答案

不幸的是,尚未完全支持在Array这样的泛型类型之间进行转换.即使您想要上流,也有一些奇怪的情况:

Unfortunately casting between generic types like Array is not fully supported (yet). There are also odd situations even if you want to upcast:

let emptyStringArray : [String] = []
emptyStringArray as [Any]    // succeeds

let stringArray : [String] = ["Bob", "Roger"]
stringArray as [Any]         // error! due to the elements?!

let intArray = [1, 2, 3]
intArray as [Any]            // error

let customStructArray : [myStruct] = []
customStructArray as [Any]   // '[myStruct]' is not convertible to '[Any]'

如果不使用协议,也没有好的解决方法.如果您确实想拥有这种动态行为,则可以在reflect()函数中使用反射.在Swift 2中,它们功能更强大,但这仍然不是一个好的解决方案.

There is also no good workaround without using a protocol. If you really want to have this dynamic behavior you could use reflections with the reflect() function. In Swift 2 they are more powerful, but it is still not a good solution.

一种具有协议的解决方案,该协议被所有Arrays通过扩展名采用(仅针对您的特定情况):

A solution with a protocol which gets adopted by all Arrays through an extension (only for your specific case):

protocol ArrayType {
    var anyValues: [Any] { get }
}

extension Array: ArrayType {
    var anyValues: [Any] {
        return self.map { $0 as Any }
    }
}

// now the switch gets rewritten as
switch any {
case let array as ArrayType:
    let anyArray = array.anyValues
    return "Array"
case let array as NSArray:
    return "NSArray"
default:
    return "Default"
}

这篇关于Array&lt; Any&gt;上的快速模式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆