如何检测该参数是两种任意类型的元组?

How to detect that parameter is a tuple of two arbitrary types?(如何检测该参数是两种任意类型的元组?)
本文介绍了如何检测该参数是两种任意类型的元组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我实际上在做的事情更复杂,但归根结底是能够实现检测某物是元组的功能,而不管其元素的类型是什么.

What I am actually doing is more complex but it comes down to being able to implement function to detect that something is a tuple, regardless of what the are the types of its elements.

这是我的方法不起作用(见最后一行的评论):

This is my approch that does not work (see comment on last line) :

func isTuple(b: Any) -> Bool {
    return b is (Any, Any)
}

let myString = "aa"
let myDouble = 1.2
isTuple((myString, myDouble)) //returns false

为什么它不起作用?Any 不应该在元组中充当通配符"吗?它是一个已知的 Swift 错误吗(如果不是,我应该将其视为一个并报告)?还有其他方法可以使 isTupple 方法起作用吗?

Why doesn't it work? Shouln't Any act as a "wildcard" in tuples as well? Is it a known Swift bug (if not should I consider it one and report)? Is there other way how to make isTupple method work?

@NateCook's answer 完全回答了原始问题,但这并不能帮助我做我想做的事情.就是这样:

@NateCook's answer fully answers original question but does it does not help me to do what I am trying to do. This is it:

我不仅需要确定某物是元组,还需要在不知道这些值的确切类型的情况下将其分解为两个值.

I need not only to determine that something is a tupple but also to break it into its 2 values without knowing the exact type of those values.

代码如下:

func processIfTuple(b: Any) {
    if reflect(b).disposition == MirrorDisposition.Tuple {
        let (first, second) = b as (Any, Any) //error when casting
        process(first)
        process(second)
    }
}

func process(value: Any) {
    ...
}

processIfTuple(("aa", 1.2))

这不起作用的原因与测试 b is (Any, Any) 不起作用的类似原因.这次尝试投射时出现错误.这可以解决吗?如果不是,是否应将其视为语言错误或缺少功能并报告?这肯定会导致大量代码重复,因为我需要为一个元组测试所有可能的类型对.

This does not work from similar reason that the test b is (Any, Any) does not work. This time there is error when trying to cast. Can this be solved? If not should it be considered language bug or missing feature and reported? It definitely leads to a LOT of code duplication because I need to test for all possible pairs of types for a tuple.

推荐答案

你可以使用 Swift 的婴儿自省方法来解决这个问题:

You can use Swift's baby introspection methods to get at this:

func isTuple(b: Any) -> Bool {
    return reflect(b).disposition == MirrorDisposition.Tuple
}

请注意,reflect 在很大程度上没有记录,可能只是作为对操场/调试器的支持,但据我所知,这是执行此操作的唯一方法.

Note that reflect is largely undocumented and may only be there as support for the playground / debugger, but as far as I know this is the only way to do this.

要实现这一点,您需要深入了解 reflect() 为您提供的内容,这是一个符合 MirrorType 的结构,我称之为反射,因为缺少一个更好的术语.您可以下标元组的反射以获取元组成员的反射,然后将值返回为 Any.此时,您可以使用可选绑定来安全地重新发现底层类型:

To achieve this you need to drill down into what reflect() gives you, which is a struct that conforms to MirrorType, which I call a reflection, for lack of a better term. You can subscript the reflection of a tuple to get reflections of the tuples members, and then get the value back out as Any. At that point you can use optional binding to safely rediscover the underlying type:

func process(value: Any) {
    println("Any (value)")
}

func process(value: String) {
    println("String (value)")
}

func processTuple(b: Any) -> Bool {
    let isTuple = reflect(b).disposition == MirrorDisposition.Tuple

    let r = reflect(b)
    for i in 0..<r.count {
        println(r[i].0)         // string holding tuple part name: ".0", ".1", etc
        println(r[i].1.value)   // the value of that tuple part: "aa", 1.2

        process(r[i].1.value)   // calls process(Any)
        if let val = r[i].1.value as? String {
            process(val)        // calls process(String)
        }
    }

    return isTuple
}

let myString = "aa"
let myDouble = 1.2
processTuple((myString, myDouble)) //returns false

输出:

.0
aa
Any aa
String aa
.1
1.2
Any 1.2

这篇关于如何检测该参数是两种任意类型的元组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

FireStore - how to get around array quot;does-not-containquot; queries(FireStore - 如何绕过数组“不包含查询)
Convert timestamp string with epochal time and timezone into NSDate(将带有纪元时间和时区的时间戳字符串转换为 NSDate)
iOS Swift - Get the Current Local Time and Date Timestamp(iOS Swift - 获取当前本地时间和日期时间戳)
Swift - iOS - Dates and times in different format(Swift - iOS - 不同格式的日期和时间)
Timestamp function that has been working reliably just caused EXC_BAD_INSTRUCTION(一直可靠工作的时间戳功能只是导致 EXC_BAD_INSTRUCTION)
Convert a Date (absolute time) to be sent/received across the network as Data in Swift?(将要通过网络发送/接收的日期(绝对时间)转换为 Swift 中的数据?)