在源或包的顶层声明时,对象表达式的范围是什么?

What is the scope of object expression when it's declared on top level of source or package?

我正在学习 Kotlin 中的 object。我无法意识到在 class 之外声明的对象的范围是什么。 例如:

val point= object {
            public var x: Int = 0
            var y: Int = 0
        }

我检查的情况(并没有得出任何结论):

  1. 当我在 class 外声明它,然后尝试在函数内使用它时,点是有效的,但成员 x 和 y 无法识别。
  2. 当我在 class 之外声明它,然后尝试将它用作 class 的成员时,那里根本无法识别它。
  3. 当我在 class(当然是 public)之外声明它时,然后尝试从另一个无法识别的源文件中使用它。

谁能帮我理解对象表达式的范围?

object 在这种情况下创建一个匿名对象 class(与 object: Any 相同)。

来自文档:https://kotlinlang.org/docs/reference/object-declarations.html#object-expressions

Note that anonymous objects can be used as types only in local and private declarations. If you use an anonymous object as a return type of a public function or the type of a public property, the actual type of that function or property will be the declared supertype of the anonymous object, or Any if you didn't declare any supertype. Members added in the anonymous object will not be accessible.

point是一个public静态变量,所以这个变量的实际类型是Any

在任何 class 之外的文件中声明的变量直接在包中声明。

来自docsobjects 强调我的):

Functions, properties and classes, objects and interfaces can be declared on the "top-level", i.e. directly inside a package:

// file name: example.kt
package foo

fun baz() { ... }
class Bar { ... }
  • If you do not specify any visibility modifier, public is used by default, which means that your declarations will be visible everywhere;
  • If you mark a declaration private, it will only be visible inside the file containing the declaration;
  • If you mark it internal, it is visible everywhere in the same module;
  • protected is not available for top-level declarations.

Note: to use a visible top-level declaration from another package, you should still import it.

Examples:

// file name: example.kt
package foo

private fun foo() { ... } // visible inside example.kt

public var bar: Int = 5 // property is visible everywhere
    private set         // setter is visible only in example.kt

internal val baz = 6    // visible inside the same module

also from the docs

Note that anonymous objects can be used as types only in local and private declarations. If you use an anonymous object as a return type of a public function or the type of a public property, the actual type of that function or property will be the declared supertype of the anonymous object, or Any if you didn't declare any supertype. Members added in the anonymous object will not be accessible.

class C {

    // Private function, so the return type is the anonymous object type
    private fun foo() = object {
        val x: String = "x"
    }

    // Public function, so the return type is Any
    fun publicFoo() = object {
        val x: String = "x"
    }

    fun bar() {
        val x1 = foo().x        // Works
        val x2 = publicFoo().x  // ERROR: Unresolved reference 'x'
    }
}

所以当你这样做时

val point= object {
    public var x: Int = 0
    var y: Int = 0
}

您正在 程序包 中创建类型 Anypublic 对象。因为类型是 Any,所以无法查找您定义的匿名对象的属性。但是,如果你制作对象private,你可以使用它:

private val point= object {
    var x: Int = 0
    var y: Int = 0
}

val x = point.x
val y = point.y
fun editPoint() {
    point.x = 1
    point.y = 2
}