tera
February 7, 2023, 1:54am
1
How do I check that a given existential value is of reference type?
I'm now doing this, is this a good approach?
func isRef(_ v: Any) -> Bool {
func opened<T>(_: T) -> Bool { false }
func opened<T: AnyObject>(_: T) -> Bool { true }
return _openExistential(v, do: opened)
}
abdel-17
(Abdelrahman)
February 7, 2023, 2:30am
2
Can't you do v is AnyObject
?
AlexanderM
(Alexander Momchilov)
February 7, 2023, 3:58am
3
You'll get false positives because of bridging, e.g. Int to NSNumber
, and wrapping to _SwiftValue
, I’m afraid
tera
February 7, 2023, 4:10am
4
it just doesn't work, e.g.:
struct S {}
S() is AnyObject // true
ibex10
February 7, 2023, 5:37am
5
func isRef(_ v: Any) -> Bool {
func opened<T>(_: T) -> Bool { false }
func opened<T: AnyObject>(_: T) -> Bool { true }
return _openExistential(v, do: opened)
}
func checkMore (_ u: Boo) -> Bool {
isRef (u)
}
protocol Boo {}
struct Bing : Boo {}
class Bong : Boo {}
let bing : Boo = Bing ()
let bong : Boo = Bong ()
print (isRef (5))
print (isRef (bing))
print (isRef (bong))
print (checkMore (bing))
print (checkMore (bong))
But that gives me:
false
false
false
false
false
xwu
(Xiaodi Wu)
February 7, 2023, 6:17am
6
func isStaticallyOfAnyObjectType<T>(_: T) -> Bool {
T.self is AnyObject.Type
}
func isDynamicallyOfAnyObjectType(_ x: Any) -> Bool {
_openExistential(x, do: isStaticallyOfAnyObjectType)
}
// Usage:
protocol P { }
class C: P { }
isDynamicallyOfAnyObjectType(42) // false
isDynamicallyOfAnyObjectType(42 as Any) // false
isDynamicallyOfAnyObjectType(C()) // true
isDynamicallyOfAnyObjectType(C() as any P) // true
6 Likes
tera
February 7, 2023, 6:23am
7
Cool, this seems to work.
Also found this one:
func isRef(_ v: Any) -> Bool {
Mirror(reflecting: v).displayStyle == .class
}
2 Likes
sveinhal
(Svein Halvor Halvorsen)
February 7, 2023, 9:00am
8
Classes aren't the only reference types, closures are too, iirc.
So are actors. The only correct answer without false positives requires you to walk over the metatypes, which is what @xwu showcased above.
3 Likes
tera
February 7, 2023, 1:07pm
10
For the record, both @xwu and Mirror version above give correct result for actors (true) and incorrect result for closures (false).
1 Like
bbrk24
February 8, 2023, 12:01am
11
I’ve solved this problem before using type(of: x) is AnyClass
. Granted, I don’t think that would work for closures, but in the context where I was using it closures weren’t an expected use-case.
2 Likes
tera
February 8, 2023, 1:20am
12
You are right, this simpler version works as good as the other two mentioned above:
func isRef(_ x: Any) -> Bool {
type(of: x) is AnyClass
}
1 Like