Kotlin中let()与also()是否支持this关键字?书籍代码编译报错求解
this keyword? Great question! Let's unpack why that code from Programming in Kotlin won't compile, and clarify how let() and also() handle the this keyword.
Core Answer
let() and also() do support the this keyword, but only if the surrounding context has a valid this to reference. The error you're seeing ('this' is not defined in this context) happens because the code is likely running in a top-level context (like a standalone script or top-level function) where there's no implicit this available.
Let's break down how these functions work with scoping:
1. How let() and also() handle lambda scoping
Both functions pass the original object as a lambda parameter (default name it, which you can customize like arg in the book's code). The key thing to note:
- Inside their lambdas,
thisrefers to the outer scope'sthis(not the object being operated on).- If you're inside a class/object member function,
thispoints to the class/object instance. - If you're in a top-level context (no enclosing class/object), there's no
thisto reference—hence the compiler error.
- If you're inside a class/object member function,
2. Why the book's code fails to compile
The book's snippet has two critical issues:
- Undefined
this: As mentioned, if this code is written in a top-level context, there's nothisavailable. - Undefined
resultvariable: The code referencesresultwithout ever defining it—this is another compile error the book likely missed as a typo.
3. Fixed examples
Example 1: Using let() and also() inside a class (valid this context)
class ScopeDemo { private val logFormat = "%-10s | arg: %s | this: %s | processed: %s%n" fun testStringOperations(str: String) { // let() returns the lambda's last expression val result1 = str.let { arg -> val processed = arg.uppercase() println(String.format(logFormat, "let", arg, this, processed)) processed } println("Final let result: $result1") // also() returns the original object (str) val result2 = str.also { arg -> val processed = arg.lowercase() println(String.format(logFormat, "also", arg, this, processed)) } println("Final also result: $result2") } } fun main() { ScopeDemo().testStringOperations("Hello Kotlin") }
Example 2: Top-level context (no this available)
Here we remove the this reference since it doesn't exist in the top-level scope:
val logFormat = "%-10s | arg: %s | processed: %s%n" fun main() { val str = "Hello Kotlin" val result1 = str.let { arg -> val processed = arg.uppercase() println(String.format(logFormat, "let", arg, processed)) processed } println("Final let result: $result1") val result2 = str.also { arg -> val processed = arg.lowercase() println(String.format(logFormat, "also", arg, processed)) } println("Final also result: $result2") }
Key Takeaways
let()andalso()don't introduce a newthisin their lambdas—they reuse the outer scope'sthis.- Use
thisinside their lambdas only if your code is in a context wherethisis defined (class members, object expressions, etc.). - The book's code has typos (undefined
result) and assumes a context wherethisexists, which isn't universal.
内容的提问来源于stack exchange,提问作者jakstack

