this 表达式
this 表达式指向当前接受者(函数作用的对象). this 的用法取决于所处的上下文:
在 类 的成员中,
this指向这个类的当前对象.例如, 在以下代码中,
this.name表示当前Language对象的name属性:class Language(val name: String) { fun printName() { println(this.name) } } fun main() { val language = Language("Kotlin") language.printName() // 输出结果为: Kotlin }在 扩展函数 中, 或 带有接受者的函数字面值 中,
this指向接受者.在以下示例中, 对字符串
"Kotlin"调用了lastCharacter(), 因此"Kotlin"是接受者. 在扩展函数内,this指向"Kotlin". 因此this.length是"Kotlin"的长度:fun String.lastCharacter(): Char { println(this.length) // 输出结果为: 6 return this[this.length - 1] } fun main() { println("Kotlin".lastCharacter()) // 输出结果为: n }
带限定符的 this
如果接受者的作用域出现嵌套, 代码中可能同时存在多个可访问的接受者. Kotlin 可以隐含的使用任何可用的接受者来访问它的成员, 但内层作用域的接受者具有更高优先级. 要明确的指向某个接受者, 请使用带限定符的 this. 如果多个接受者具有同名的成员, 而你需要访问外层接受者的成员, 这种写法尤其有用.
要使用带限定符的 this, 请添加 标签 限定符:
标签会告诉编译器要访问哪个接受者. 你可以使用外层类或扩展函数的名称. 例如, this@foo 指向名为 foo 的外层扩展函数的接受者.
从内部类访问外部类
在 内部类(Inner class) 中, 无限定符的 this 指向内部类的实例. 要访问外部类(Outer Class)对象, 请使用带限定符的 this:
从扩展函数访问类
如果在类内部声明扩展函数, 那么会存在两个可访问的接受者:
扩展接受者(Extension Receiver): 对其调用扩展函数的值.
派发接受者(Dispatch Receiver): 声明扩展函数的类的当前对象.
请使用带限定符的 this 指明你需要的接受者:
在这个示例中:
this指向扩展接受者 (String), 因此this.uppercase()会将字符串转换为大写.this@User指向当前User对象.this@User.prefix访问当前User对象的prefix属性.
在 Lambda 表达式中访问
与通常的 Lambda 表达式不同, 带接受者的 Lambda 表达式 会在它的作用域中引入一个接受者. 因此, Lambda 表达式内的 this 指向这个 Lambda 表达式的接受者, 而不是外层作用域的接受者. 如果带接受者的 Lambda 表达式嵌套在另一个接受者的作用域之内, 请为 Lambda 表达式添加标签, 并使用带限定符的 this, 明确的指向 Lambda 表达式的接受者, 或指向外层作用域的接受者:
在这个示例中:
stringLabel@为 Lambda 表达式添加标签.this@stringLabel指向 Lambda 表达式的字符串接受者.this@User指向当前User对象.
标签不会调用任何内容, 也不会改变 Lambda 表达式的工作方式. 它只是帮助你引用 Lambda 表达式的接受者.
访问匿名对象或它的外部类
匿名对象 有它自己的接受者作用域. 在对象体内部, 无限定符的 this 指向匿名对象本身. 但是, 匿名对象没有类名, 因此不能用它的类名作为 this 的限定符. 所以, 只能通过无限定符的 this 指向匿名对象:
如果在另一个类的内部声明匿名对象, 可以使用带限定符的 this 访问外层对象:
隐含的 this
在 this 上调用成员函数时, 可以省略 this. 限定符. 但是, 如果在更近的词法作用域内存在其他同名的可调用对象, Kotlin 会将无限定符的调用解析为这个对象, 而不是成员函数. 要明确的调用成员函数, 请使用 this. 限定符: