提问人:Dmitrii Rashchenko 提问时间:8/7/2021 更新时间:8/7/2021 访问量:539
如何访问顶级对象的字段?
How to access the field of top-level object?
问:
当我这样做时
val data = object {
val field = 5
}
fun main(){
println(data.field) // throws
}
它抛出.Unresolved reference: field
但这一切都没关系:
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
}
我不明白,为什么 Kotlin 不允许我使用顶级对象的属性?我认为这就像类对象一样,但匿名(没有类),并且在上面的示例中和之间应该没有区别。但似乎有区别。object
data
data7
答:
8赞
Sweeper
8/7/2021
#1
这记录在语言规范的“对象文本”部分,其中介绍了对象声明和匿名对象(对象文本创建的内容)之间的区别。
常规对象声明和匿名对象之间的主要区别在于其类型。匿名对象的类型是一种特殊的类型,只有在声明它的作用域中才可用(和可见)。它类似于常规对象声明的一种类型,但是,由于它不能在声明范围之外使用,因此具有一些有趣的效果。
你的这里被认为已经逃脱了“文件的顶层”的声明范围,因为它是公开的。您可以从其他文件的顶级范围访问它。data
注意:在此上下文中,如果将相应的值声明为非私有全局或分类器范围属性,则会立即执行“转义当前范围”,因为这些属性是外部可访问接口的一部分。
标记它会修复它。错误的原因是:private
当匿名对象类型的值转义当前作用域时:
- 如果该类型只有一个声明的超类型,则将其隐式向下转换为此声明的超类型;
- 如果该类型具有多个声明的超类型,则必须对作用域外可见的任何合适类型进行隐式或显式强制转换,否则就是编译时错误。
这里超类型是隐式的,所以类型是,显然类型上没有。Any
data
Any
field
Any
另一方面,have 没有转义当前作用域,因为它是函数的语句作用域的局部作用域。无法从其他作用域访问它。data4
main
另请参阅规范中的优秀示例。
评论