You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中let()与also()是否支持this关键字?书籍代码编译报错求解

Are Kotlin's let() and also() methods supporting the 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, this refers to the outer scope's this (not the object being operated on).
    • If you're inside a class/object member function, this points to the class/object instance.
    • If you're in a top-level context (no enclosing class/object), there's no this to reference—hence the compiler error.

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 no this available.
  • Undefined result variable: The code references result without 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() and also() don't introduce a new this in their lambdas—they reuse the outer scope's this.
  • Use this inside their lambdas only if your code is in a context where this is defined (class members, object expressions, etc.).
  • The book's code has typos (undefined result) and assumes a context where this exists, which isn't universal.

内容的提问来源于stack exchange,提问作者jakstack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:33:03