I know you can use `obj::class` to check if object...
# getting-started
r
I know you can use
obj::class
to check if objects are instances of a type
Copy code
abstract class Base { }
class SubA : Base()

fun fn(obj: Base, t: KClass<out Base>) {
    if (obj::class == t) {}
}
fun main() {
    val a = SubA()
    fn(a, SubA::class)
}Is there any possible way to mimic this behavior by using
::Foo
instead
Copy code
abstract class Base { }
class SubA : Base()
//                       v different
fun fn(obj: Base, t: KFunction<Base>) { 
    if (obj::class == t) {}
}
fun main() {
    val a = SubA()
    fn(a, ::SubA) // <- different
}
g
What do you want to achieve with that?
Foo
is a type that is compared with
is
::Foo
is a reference to a function. Why would you want to compare in object with a function? What you can do:
Copy code
val x = ::Foo
if (x == ::Foo)
Here you are comparing two function references. Does that help?
r
@Goetz Markgraf I want to never have to write
SubA::class
btw updated my question to be more clear
old
Copy code
abstract class Base { }
class SubA : Base()

fun fn(obj: Base, t: KClass<out Base>) {
    if (obj::class == t) {}
}
fun main() {
    val a = SubA()
    fn(a, SubA::class)
desired
Copy code
abstract class Base { }
class SubA : Base()
//                       v different
fun fn(obj: Base, t: KFunction<Base>) { 
    if (obj::class == t) {}
}
fun main() {
    val a = SubA()
    fn(a, ::SubA) // <- different
}
SubA::class
is very verbose and ugly
and I my entire game framework is centered around this
so I type it hundreds of times
Copy code
entity.hasComponents(::Physics, ::Graphics, ::Health)
is much cleaner than
Copy code
entity.hasComponents(PHysics::class, Graphics::class, Health::class)
I get ::SubA refers to the constructor rather than the type
just wondering if there is a hack I can use to convert that internally
g
I don’t see, why
::class
is ugly, but that depends on taste. As I have said,
::something
is a pointer to a function not to a type.
r
it's verbosity is clear though
in typescript you can just say the class
Physics
As I have said,
::something
is a pointer to a function not to a type.
yeah so Is there a way to say "this object's types constructor is equivalent to this function"?
like
if (::(obj::class) == fn)
where fn is
::Foo
g
in typescript you can just say the class
Typescript does not really have classes, the concepts cannot be compared. Maybe there is an alternative. Do all your type inherit from a single base type? Then you might add a function for comparison there taht “redirects” to an enum. Of course, you with have to manually sync you enum to your types. If your types seldom change, that might be another way.
r
the design patterns I use involve you constantly passing around literal classes rather than instances. Hundreds of times. the
::class
adds up
I just want to find a way to make that cleaner
so I don't have to live with it for years
g
🤷 Maybe someone else has an idea
r
they all share a base
Component
class
but yeah I'm not going to do 2x the work creating a corresponding enum for every single new component i add
r
with reified generics you can 'fix' the specific example you mentioned:
Copy code
abstract class Base
class SubA : Base()

inline fun <reified T : Base> fn(obj: Base) {
    if (obj is T) {}
}
fun main() {
    val a = SubA()
    fn<SubA>(a)
}
but that does mean inlining the function, and you'd really have to wonder if it's worth it all just because you find
::class
ugly...
r
@Riccardo Lippolis Would that work for vararg functions? I need to be able to write stuff like
Copy code
val Monitor = MonitorEntities(Physics::class, Gravity::class, Spatial::class, Material::class, Mesh::class)
with your example I would imagine it would be
Copy code
val Monitor = MonitorEntities<Physics, Gravity, Spatial, Material, Mesh>()
but is that possible?
r
as far as I know you can't define a function with a variable number of generic types, you'd need multiple functions
r
I have found out that you can pass literal classes like
Copy code
fn(Physics)
if they have a companion object. ...but kotlin outlaws putting a single companion object on a base class to be inherited for all subclasses (arbitrarily, because they thought it was "too confusing"). So I would have to redundantly redefine the exact same companion object for every single subclass. (so, hundreds of times realistically)
this guy is managing to do some crazy syntax tricks or "templating" (whatever that means) to get it working.
i don't understand it though
t
Maybe do
val CSubA = SubA::class
as a global?