What's the type of an object expression?


#1

This works:

class X(n: Int) {
  val foo = object {
    val bar = n * 2
  }.bar
}

This does not work:

class X(n: Int) {
  val foo = object {
    val bar = n * 2
  }
  fun y() = foo.bar // bar can't be resolved
}

If this is expected, is there another way to declare a foo namespace inside X (with access to X’s instance state)? Would be very handy in some cases, e.g. to group related properties in a class.


#2

Yes, this is expected. Properties declared in a class need to have a non-anonymous type, so if you’re not explicitly specifying the supertype of object, the type of foo in the second example will be Any.

For grouping related members of the class, I think it’s best to use features that don’t impact the runtime behavior of a class, such as folding regions in the IDE.


#3

What I’m looking for is a grouping that’s visible at call sites, e.g. metrics.foo, metrics.bar, metrics.baz with two-stage auto-completion.


#4

Can you use named objects?


#5

That was my initial hope, but as far as I can tell, named objects cannot access instance state (or at least constructor arguments) of the enclosing class, as in my example.


#6

Have you tried using an inner class?


#7

That would work, but declaring a private named inner class, creating a single instance, and assigning it to a private property feels a bit too indirect/verbose for my needs. I just wanted to make sure that I’m not missing a way to achieve this with object expressions or a similar language feature, given that object { val foo = 1 }.foo actually works.

I think it’s safe to say by now that there is no easier way than an inner class. Thanks for the suggestion!