[英]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 (块)中的this
与let
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
:另一个同时使用
this
和it
的例子:
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.