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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With