一尘不染

如何测试泛型变量是否为AnyObject类型

swift

在Swift3中,我不再能够检查泛型变量类型是否为class(AnyObject)。下面的代码返回trueisObject即使特定类型T,并通过价值结构,而不是类。在Swift2.3和2.2中,它可以按预期工作,并且isObjectfalse

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中正常工作?


阅读 272

收藏
2020-07-07

共1个答案

一尘不染

在Swift3中,AnyObject由于引入了所有内容_SwiftValue,因此可以将所有不能直接桥接到Objective-
C的内容包装在一个不透明的Objective-C兼容框中。

因此is AnyObject将永远是真实的,因为任何东西都可以表示为AnyObject通过在包装_SwiftValue

检查值是否为一个引用类型)是键入检查的值的类型对的元类型AnyObjectAnyClass(又名AnyObject.Type)。

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

isObject = T.self is AnyClass

如果要检查 键入 为的值的 动态类型
是否为T引用类型(例如,val在您的示例中),则可以type(of:)对未包装的值使用该函数,如前面的问答所述:

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

    // ...
}

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

2020-07-07