如何测试泛型变量是否为 AnyObject 类型 [英] How to test whether generic variable is of type AnyObject
问题描述
在 Swift 3 中,我不再能够检查泛型变量类型是否为类 (AnyObject
).即使特定类型 T
和传递的值是结构而不是类,以下代码为 isObject
返回 true
.在 Swift 2.3 和 2.2 中,它按预期工作,isObject
为 false
.
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 中,由于 _SwiftValue
(参见 this Q&A 了解更多信息),它可以将任何不能直接桥接到 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
将始终为真,因为任何东西都可以通过包装在 _SwiftValue
中表示为 AnyObject
.
Therefore is AnyObject
will always be true, as anything can be represented as an AnyObject
via wrapping in a _SwiftValue
.
一种检查值是否为引用类型的方法(如本问答中所示;A) 是根据 AnyObject
、AnyClass
(又名 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
的值的 dynamic type 是否是一个引用类型(比如你的例子中的 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
// ...
}
这两种方法的区别在于,当 T
是 Any
类型(或非 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屋!