简体   繁体   English

在发送给 let 函数的 lambda 表达式中使用“this”会发生什么?

[英]What happens when using 'this' inside a lambda expression that is sent to let function?

I've looked at the source code of let function:我查看了let函数的源代码:

    @kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}

i clearly understand that using it keyword inside of the block (code) i'm sending to let function will refer to the object that called the let function.我清楚地明白,在我发送给 let 函数的块(代码)中使用it关键字将引用调用let函数的对象。 But on which object does this keyword will refer if i will use it inside the block (code).但是如果我将在块(代码)中使用它,这个关键字将引用哪个对象。 The way i see it, it should be the same object that it refer to, but i'm not sure.我看它的方式,它应该是所指的同一个对象,但我不确定。 My computer gone bad so i can't test it by myself.我的电脑坏了,所以我不能自己测试。 Can someone not only give me the answer but also will explain me the logic behind the this keyword in the situation above?有人不仅可以给我答案,而且可以解释我在上述情况下this关键字背后的逻辑吗?

example of code:代码示例:

val p:Preson = Person()
p.let{**this**}

this in the let lambda (block) means the same thing as it does outside the let lambda. let lambda (块)中的thislet lambda 之外的含义相同。 The let lambda does not suddenly "change" what this means. let lambda 不会突然“改变” this意味着什么。

For example:例如:

class Foo {
    fun foo() {
        // here, "this" refers to the receiver of foo(), i.e. some instance of Foo
        1.let {
            // here, "it" refers to 1, 
            // and "this" refers to the receiver of foo() too
        }
    }
}

fun main() {
    // here, "this" does not mean anything, main() has no receiver
    2.let {
        // here, "it" refers to 2, 
        // and "this" does not mean anything either
    }
}

This is because this refers to the receiver of a function, but the function type of the parameter that let takes has no receiver:这是因为this指的是函数的接收者,但是let接受的参数的函数类型没有接收者:

public inline fun <T, R> T.let(block: (T) -> R): R {
                                      ^^^^^^^^

Compare that to run , which is very similar to let , except its receiver as the receiver of the block parameter:将其与run进行比较,这与let非常相似,只是它的接收器是block参数的接收器:

public inline fun <T, R> T.run(block: T.() -> R): R {
    return this.block() // instead of block(this) like let
}

which means that:意思就是:

1.let {
    // here, "this" refers to 1
    // "it" does not mean anything because the function type T.() -> R has no parameters
}

Another example that uses both this and it :另一个同时使用thisit的例子:

fun usesBoth(x: Int, y: String, block: Int.(String) -> Unit) {
    x.block(y)
}

If you call usesBoth with a lambda,如果您使用 lambda 调用usesBoth

usesBoth(1, "x") {
    println(this) // prints 1
    println(it)   // prints x
}

this in the lambda would refer to 1, because block is called on x in usesBoth , and it would refer to "x", because y is passed to block as a parameter. lambda 中的this将引用 1,因为在usesBoth中对x调用了block ,并且it引用“x”,因为y作为参数传递给block

this is just one of parameters (called a "receiver") that could be passed to the lambda by a calling code. this只是可以通过调用代码传递给 lambda 的参数之一(称为“接收器”)。 If lambda doesn't support a receiver, as in the let example, this will be just this of the enclosing code:如果 lambda 不支持接收器,如在let示例中, this将只是封闭代码的this

class Foo {
    fun foo() {
        val p = Person()
        p.let{ this } // `this` is `Foo`
    }
}

If lambda has a receiver then it depends what will be passed to it as this .如果 lambda 有一个接收器,那么它取决于将作为this传递给它的内容。 For example, a very similar function to let , but passing the object as this is apply :例如,一个与let非常相似的函数, this传递对象是apply

class Foo {
    fun foo() {
        val p = Person()
        p.apply{ this } // `this` is `Person`
    }
}

Of course, this doesn't have to be the object that we invoked the function on.当然, this不一定是我们调用函数的对象。 It could be just any object, it depends on what the function will pass to the lambda.它可以是任何对象,这取决于函数将传递给 lambda 的内容。 For example, in Kotlin stdlib we have a buildString() function that instantiates a StringBuilder , runs the lambda passing the StringBuilder as this and then returns a string that was built by the lambda.例如,在 Kotlin 标准库中,我们有一个buildString()函数,它实例化一个StringBuilder ,运行 lambda 并将StringBuilder作为this传递,然后返回一个由 lambda 构建的字符串。 We use this function like this:我们像这样使用这个函数:

val s = buildString {
    // `this` is `StringBuilder`
    append("hello") // implicit this.append()
    append("world")
}

By looking into buildString() signature we can see that the lambda receives StringBuilder as its receiver:通过查看buildString()签名,我们可以看到 lambda 接收StringBuilder作为其接收者:

public inline fun buildString(builderAction: StringBuilder.() -> Unit): String {

You can read more about lambdas with receivers in the documentation: https://kotlinlang.org/docs/lambdas.html您可以在文档中阅读有关带有接收器的 lambda 的更多信息: https ://kotlinlang.org/docs/lambdas.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实时数据可观察到的Kotlin的lambda表达式中的“ let”是什么意思 - What does 'let' mean in lambda expression for livedata observable Kotlin 如何在 lambda 表达式中使用 kotlin 中的替换 function 将字母替换为数字 - How do I replace letters with numbers using the replace function in kotlin inside a lambda expression 在 Kotlin 中使用 Lambda 表达式实现函数接口 - Implementing Function Interface using Lambda Expression in Kotlin lambda表达式的函数 - Function to lambda expression 如何打破“let”lambda 中的 forEach 循环? - How to break forEach loop inside "let" lambda? Kotlin字符串中的Lambda表达式 - Lambda expression inside Kotlin String 当用户在 function 中间离开应用程序时会发生什么? - What happens when the user leaves the app in the middle of a function? Kotlin-使用..创建范围或如何执行区间时会发生什么? - Kotlin - What happens when a range is created using .. or how it performs compartaions? 在lambda表达式中使用rxjava2 completable时的显式返回类型 - explicit return type when using rxjava2 completable in lambda expression 在 kotlin 中使用“let”时,我的变量名和“it”有什么区别? - What is the difference between my variable name and 'it' when using 'let' in kotlin?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM