Kotlin:IT和THIS关键字之间的区别

mwg9r5ms  于 2022-11-16  发布在  Kotlin
关注(0)|答案(6)|浏览(291)

在Kotlin的一次采访中,有人问我itthis关键词之间的区别。
我在谷歌上搜索了一下,但找不到这个问题的合适答案。
谁能告诉我这两者之间的实际区别是什么?
我知道这是很基本的问题,我是Kotlin的新手。

7uzetpgm

7uzetpgm1#

it只在一个lambda中有一个参数。它是一个参数的默认名称,也是一个简化的名称,允许你省略命名这个参数。一个这样声明的函数看起来可能是这样的:

(String) -> Unit

在lambda中,this是receiver参数。它只在函数定义为具有接收方时有效,如下所示:

String.() -> Unit

如果函数声明没有接收器,那么this在lambda作用域之外的意义是相同的。对于扩展函数,它是扩展函数的接收器。否则,它是包含函数的类。

tnkciper

tnkciper2#

您需要了解Scope Functions
Kotlin标准库包含几个函数,它们的唯一目的是在对象的上下文中执行代码块。当你在一个对象上调用这样的函数时,它会形成一个临时作用域。
在此范围内,存在一个上下文对象thisit
在Scope函数runapplywith中,作用域(临时)更改为您在其上调用此函数的对象的作用域:

val str = "Hello"
str.run {
    //Here this refers to str
}

在Scope函数letalso中,作用域没有改变(保持与调用者作用域相同),但是您的lambda将在lambda中接收作为it的上下文:

val str = "Hello"
str.let {
    //Here it refers to str
}

您可以查看链接以了解更多信息。

dsf9zpds

dsf9zpds3#

itthis关键字之间的区别可以通过以lambda方法接收器 (也称为高阶函数) 为例来解释。

假设你已经写了一个函数或者使用了一个函数,它提供了回调函数作为lambda方法的接收器。一月一日
因此,有两种可能的回调方式:

*正在提供回调参数

  • 参数通过回调意味着您希望为回调提供一个参数,调用者可以在调用时使用该参数,也被认为是it

上面所写的内容只是指:(Int) -> Unit.此函数方法参数可以在调用时为您提供整数。
查看下面的片段:

fun someMethodWithCallback(callback: (Int) -> Unit) {
    callback(0)
}

// On the time of consumption, the `Int` parameter by default exposed to callback as it parameter.
obj.someMethodWithCallback { it -> // Here it is the method parameter of callback that we passed, you can also rename it to any other named value
    // it can be directly used as Int value if needed or you can rename it at receiver above
}
  • 注意:您可以提供多个参数给callback,然后您将无法接收,而callback将提供您传递的变量的数量。*
    *正在提供要回调的对象
  • 提供回调另一种方法是提供对象本身作为回调参数这意味着回调语法稍有改变,并提供对象本身作为回调参数this

上面所写的内容只是指:Int.() -> Unit.此函数方法对象可以在调用时为您提供整数。
查看下面的片段:

fun someMethodWithCallback(callback: Int.() -> Unit) {
    callback(0)
}

// On the time of consumption, the `Int` parameter by default exposed to callback as it parameter.
obj.someMethodWithCallback { this // Here this is the method object of callback that we passed, you can not rename it to anything else
    // it can be used as Int value by referencing as this
}

希望它讲得通!

slhcrj9b

slhcrj9b4#

我想走极端基本没有花哨的话。

it关键字

当你有一个参数时,你可以用it关键字调用它,它在霍夫中工作得很好,例如,

private fun itKeyword(itKeyword:(String) -> Unit) {
        itKeyword("")
    }

    fun callItFun() {
        itKeyword {//it:String // this is high light over here like this

        }

但如果你尝试这样做:

private fun itKeyword(itKeyword:(String, Int) -> Unit) {
        itKeyword("", 1)
    }

    fun callItFun() {
        itKeyword {yourName, age -> //yourName, age is define by user
        }
   }

看到了吗?编译器在这里没有定义it关键字,但是我们在定义霍夫时必须传递两个参数,但是如果我们保持这个为空,编译器会给予我们错误 * 嘿,传递一些东西,伙计,我不知道你在说什么变量这里传递了两个变量。*
这意味着,当您只有一个参数时,可以使用 it 关键字调用它。

此关键字

有两个作用域或变量/属性全局和局部作用域,当你已经定义了某个变量作为全局作用域,并且你想在多个方法/函数中调用它,而在某些地方你必须在局部作用域中使用另一个具有相同名称的相同类型的变量时,在这种情况下,我们将使用这个关键字,为什么会这样?

private lateinit var mContext: Context

    fun thisKeyword(mContext: Context) {
        this.mContext = mContext
    }

但如果我们不使用 this 关键字,而是将其保持为:

private lateinit var mContext: Context
    fun thisKeyword(mContext: Context) {
        mContext = mContext
    }

编译器会说,* 我的天啊,你做了什么,我脑子里没想起什么吗 * JK,编译器会说,* 瓦尔不能重新分配 *,等等什么?我们没有初始化它作为一个瓦尔,但如果我们看到在全局范围,我们有初始化它作为var,但你猜怎么着?编译是正确的。在Kotlin当传递到函数参数的东西,他们作为一个Val默认这意味着没有 * 这个 * 编译器使用的是局部作用域变量,而不是全局作用域,但是当我们使用 this 关键字时,我们告诉编译器,使用关键字this属性,在这里,before =是全局作用域this.mContext,after =是局部作用域,所以这就是我们使用this关键字避免变量冲突的原因。
我希望这对你有帮助,thankYou()。

dly7yett

dly7yett5#

如果这对某人有帮助:
具有如下范围:run,apply,with,来调用对象的方法,我们可以直接调用它们,因为它有对象的作用域。换句话说,run-block有“this”作用域。

private fun methodWithRun() {

    val dummy = Dummy()
    dummy.run {
        this.dummyFun()
        this.dummyVar = "10"
    }
    
}

而范围则像:同样,要调用对象的方法,我们可以使用“it”来调用它们,因为它具有编写此方法的类的作用域。

private fun methodWithLet() {
    
    val dummy = Dummy()
    dummy.let {
        it.dummyFun()
        it.dummyVar = "10";
    }
    
}
jfewjypa

jfewjypa6#

如果你看一下Kotlin作用域函数doc:
https://kotlinlang.org/docs/scope-functions.html
其中一些在作用域中使用“this”,而另一些使用“it"。区别如下:

**this:当您使用使用“this"的作用域函数时,例如apply {}**它会将函数作用域的上下文更改为调用此函数的对象的上下文,例如:

//Outer context in outer scope

val alice = Person("Alice").apply {

//Person object's context in function's inner scope

this.age = 20   //"this" refers to the object's context 
city = "London" //you can skip writing "this" because you are in the context of object
}

it:当您使用使用“it"的函数时,例如**also {}**it DOES NOT更改函数作用域的上下文,因此它与调用函数时的上下文保持相同,例如:

//Outer context in outer scope

val alice = Person("Alice").also {

//Same outer context in function's inner scope

it.age = 20        //"it" refers to the object's reference holder e.g. alice
it.city = "London" //you can not skip writing "it" because you are in outer context
}

**注意:**上下文和作用域是两件不同的事情。在这两种情况下,作用域都发生了更改,因此如果在该作用域中声明局部变量,则从外部作用域看不到该变量;在一种情况下,上下文发生了更改,而在另一种情况下,上下文保持不变,因此使用了“this”和“it”。

相关问题