如何测试泛型变量是否为AnyObject类型 [英] How to test whether generic variable is of type AnyObject

查看:207
本文介绍了如何测试泛型变量是否为AnyObject类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Swift 3中,我不再能够检查泛型变量类型是否为class(AnyObject).即使特定类型T和传递的值是struct而不是class,以下代码也会为isObject返回true.在Swift 2.3和2.2中,它可以按预期工作,并且isObjectfalse.

In Swift 3 I am no longer able to check whether generic variable type is class (AnyObject) or not. Following code returns true for isObject even though specific type T and passed value is struct and not class. In Swift 2.3 and 2.2 it works as expected and isObject is false.

struct Foo<T>
{
    var value: Any?
    var isObject: Bool = false

    init (val: T?)
    {
        if val != nil
        {
            // following line shows warnings in Swift 3
            // conditional cast from 'T?' to 'AnyObject' always succeeds
            // 'is' cast is always true
            isObject = val is AnyObject

            self.value = val
        }
    }
}

struct Bar
{
    var bar = 0
}

let b = Foo<Bar>(val: Bar())

print(b.isObject) // -> true

如何使它在Swift 3中正常工作?

How can I make it work properly in Swift 3?

推荐答案

在Swift 3中,由于引入了此问题和解答(以了解更多信息),它可以在不透明的,与Objective-C兼容的盒子中包装任何无法直接桥接到Objective-C的东西.

In Swift 3, everything is bridgeable to AnyObject due to the introduction of _SwiftValue (see this Q&A for more info), that can wrap anything that isn't directly bridgeable to Objective-C in an opaque Objective-C compatible box.

因此is AnyObject将始终为true,因为通过包装在_SwiftValue中,任何内容都可以表示为AnyObject.

Therefore is AnyObject will always be true, as anything can be represented as an AnyObject via wrapping in a _SwiftValue.

一种检查值是否为引用类型的方法(如此问题与解答; A )是根据AnyObjectAnyClass(又名AnyObject.Type)的元类型对值的类型进行类型检查.

One way to check whether a value is a reference type (as shown in this Q&A) is to type-check the type of the value against the metatype of AnyObject, AnyClass (aka AnyObject.Type).

对于泛型,如果要检查T的静态类型是否为引用类型,则可以执行以下操作:

For generics, if you want to check whether the static type of T is a reference type, you can do:

isObject = T.self is AnyClass

如果要检查键入为T的值的动态类型是否为引用类型(例如示例中的val),则可以使用type(of:)函数正如前面提到的问题与解答所建议的那样:

If you want to check whether the dynamic type of a value typed as T is a reference type (such as val in your example), you can use the type(of:) function on the unwrapped value, as the aforementioned Q&A suggests:

if let val = val {
    isObject = type(of: val) is AnyClass

    // ...
}

这两种方法之间的区别在于,当TAny类型(或非AnyObject抽象类型)时,T.self is AnyClass将返回false(如果您想要一个盒子,这可能会很有用(值可以是引用或值类型的地方)–但是,type(of: val) is AnyClass将返回val本身是否为引用类型.

The difference between these two approaches is that when T is of type Any (or a non AnyObject abstract type), T.self is AnyClass will return false (which could be useful if you want a box where the value could be a reference or value type) – type(of: val) is AnyClass however, will return whether val itself is a reference type.

这篇关于如何测试泛型变量是否为AnyObject类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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