Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access the field of top-level object?

Tags:

kotlin

When I do this

val data = object {
    val field = 5
}

fun main(){
    println(data.field)  // throws
}

It throws Unresolved reference: field.

But all of this is ok:

val field = 6

class Data(val field: Int = 7)
val data7 = Data()

fun main(){
    val data4 = object {
        val field = 4
    }
    println(field)  // ok
    println(data4.field)  // ok
    println(data7.field)  // ok
}

I do not get it, why Kotlin does not let me use properties from top-level objects? I thought that object is just like class object, but anonymous (without class) and there should be no difference between data and data7 in examples above. But it seems that there is difference.

like image 240
Dmitrii Rashchenko Avatar asked Aug 07 '21 07:08

Dmitrii Rashchenko


1 Answers

This is documented in the "Object Literals" section of the Language Specification, about the difference between object declarations and anonymous objects (the things that object literals create).

The main difference between a regular object declaration and an anonymous object is its type. The type of an anonymous object is a special kind of type which is usable (and visible) only in the scope where it is declared. It is similar to a type of a regular object declaration, but, as it cannot be used outside the declaring scope, has some interesting effects.

Your data here is considered to have escaped the declaring scope of "the top level of the file", because it is public. You can access it from the top level scopes of other files.

Note: in this context “escaping current scope” is performed immediately if the corresponding value is declared as a non-private global- or classifier-scope property, as those are parts of an externally accessible interface.

Marking it private would have fixed it. The reason for the error is that:

When a value of an anonymous object type escapes current scope:

  • If the type has only one declared supertype, it is implicitly downcasted to this declared supertype;
  • If the type has several declared supertypes, there must be an implicit or explicit cast to any suitable type visible outside the scope, otherwise it is a compile-time error.

Here, the super type is implicitly Any, so the type of data is Any, and obviously there is no field on the type Any.

On the other hand, data4 have not escaped the current scope, because it is local to the main function's statement scope. You can't access it from another scope.

See also the great example from the spec.

like image 166
Sweeper Avatar answered Oct 31 '22 19:10

Sweeper