当我这样做时
val data = object {
val field = 5
}
fun main(){
println(data.field) // throws
}
Run Code Online (Sandbox Code Playgroud)
它抛出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
}
Run Code Online (Sandbox Code Playgroud)
我不明白,为什么 Kotlin 不允许我使用顶级对象的属性?我认为这object就像类对象一样,但匿名(没有类)data并且data7在上面的示例中和之间应该没有区别。但是好像有区别。
这记录在语言规范的“对象文字”部分,关于对象声明和匿名对象(对象文字创建的东西)之间的区别。
\n\n\n常规对象声明和匿名对象之间的主要区别在于其类型。匿名对象的类型是一种特殊类型,仅在声明它的范围内可用(且可见)。它类似于常规对象声明的类型,但由于它不能在声明范围之外使用,因此具有一些有趣的效果。
\n
您的data此处被认为逃脱了“文件顶层”的声明范围,因为它是公共的。您可以从其他文件的顶级范围访问它。
\n\n注意:在这种情况下,如果相应的值被声明为非私有全局或分类器范围属性,则立即执行\xe2\x80\x9cecaping当前范围\xe2\x80\x9d,因为这些是外部可访问接口的一部分。
\n
标记它就private可以修复它。错误的原因是:
\n\n当匿名对象类型的值脱离当前范围时:
\n\n
\n- 如果该类型只有一个声明的超类型,则它会隐式向下转换为该声明的超类型;
\n- 如果该类型有多个声明的超类型,则必须隐式或显式转换为范围外可见的任何合适的类型,否则会出现编译时错误。
\n
这里,超类型是隐式的Any,所以类型上 data是,而类型上Any显然没有。fieldAny
另一方面,data4没有转义当前作用域,因为它是main函数的语句作用域的本地范围。您无法从其他范围访问它。
另请参阅规范中的精彩示例。
\n| 归档时间: |
|
| 查看次数: |
69 次 |
| 最近记录: |