Uniquely identifying a type?

Is there a way to get at a unique identifier for types? I'm doing some interesting things with protocols and find myself needing this for internal bookkeeping. Here's an example of the problem I'm encountering:

protocol M {

}

extension M {
    func whoami() -> String {
        return "\(Self.self)"
    }
}


struct A: M {

}

class B {
    struct A: M {

    }

    let a = A()
}

let a = A()
let b = B()
print("Hello")

print("a: \(a.whoami())")
print("b.a: \(b.a.whoami())")

This outputs:

a: A
b.a: A

However, I'd like to be able to disambiguate between the global "A" type and the "A" defined within class "B". I've tried looking at type(of: self) and Mirror(reflecting: self), but those seem to output the same value. Seems like if there's a way at getting the mangled compiled symbol name, that might solve my problem, but I don't see a way to get at that programmatically.

The only solution I've found is to do something like this:

protocol M {
    static var _typeId: UUID { get }
}

But it forces all conformers to add some boilerplate static var _typeId = UUID() that just adds noise.

I tried extending the protocol:

extension M {
    static var _typeId = UUID()
}

But then I get an error: static stored properties not supported in protocol extensions

Anyone have any other suggestions that's cleaner for protocol conformers?

1 Like

ObjectIdentifier(T.self)

7 Likes

That's perfect! Thank you!