当前位置: 首页 > article >正文

kotlin的this和it用法

this用法

this 在 Kotlin 中用于引用当前对象实例,在嵌套类、Lambda、匿名对象等上下文中具有灵活用法。
可以通过 标签化的 this 区分不同作用域的对象。在 高阶函数(如 apply、with)中,this 代表 Lambda 的接收者对象,使代码更加简洁,这些用法让 Kotlin 中的 this 比传统的 Java 更加灵活和强大,特别是在函数式编程和嵌套类的上下文中。

1. 类中的 this

在类的成员方法或属性中,this 用于引用当前对象的实例。

class Person(val name: String) {
    fun introduce() {
        println("Hello, my name is ${this.name}.")
    }
}
fun main() {
    val person = Person("Alice")
    person.introduce() // 输出: Hello, my name is Alice.
}

这里的 this.name 明确表示访问当前对象的 name 属性。
可选用法: 如果没有歧义,可以省略 this,直接写成 name。

2. 构造函数之间的调用 (this(…))

在主构造函数中可以通过 this(…) 调用类的其他次构造函数。

class Animal(val name: String) {
    constructor(name: String, age: Int) : this(name) {
        println("Animal's name is $name and age is $age.")
    }
}
fun main() {
    val dog = Animal("Dog", 5)
}

解释: this(name) 调用了主构造函数。

3. 扩展 this 的作用域

3.1 嵌套类或内部类中的 this

如果类包含嵌套类或内部类,我们可以使用 标签化的 this 来区分不同作用域的对象。

class Outer {
    val outerName = "Outer"

    inner class Inner {
        val innerName = "Inner"

        fun printNames() {
            println(this.innerName)          // 引用内部类的属性
            println(this@Outer.outerName)    // 引用外部类的属性
        }
    }
}
fun main() {
    val outer = Outer()
    val inner = outer.Inner()
    inner.printNames()
}

解释:
this.innerName 引用的是内部类的属性。
this@Outer.outerName 明确引用了外部类的属性。

3.2 Lambda 中的 this

在 Lambda 表达式中,this 仍然指向外部类或对象的实例,而不是 Lambda 自己的作用域。

class Car(val name: String) {
    fun start() {
        println("$name started!")
    }

    fun drive(action: () -> Unit) {
        action() // 调用传入的 Lambda
    }
}

fun main() {
    val car = Car("Tesla")
    car.drive {
        this.start() // this 指向的是 Car 实例
    }
}

解释: Lambda 表达式中的 this 引用的是 Car 类的当前实例。

4. 带接收者的 Lambda(如 apply 和 with)中的 this

Kotlin 的 apply、with 等高阶函数使用 带接收者的 Lambda,其中 this 代表当前 Lambda 的接收者对象。

4.1 apply 示例
class Person {
    var name: String = ""
    var age: Int = 0
}

fun main() {
    val person = Person().apply {
        this.name = "Alice"
        this.age = 25
    }
    println("Name: ${person.name}, Age: ${person.age}")
}

解释: apply 中的 this 指向 Person 对象,因此可以直接访问或修改其属性。

4.2 with 示例
fun main() {
    val person = Person()
    with(person) {
        name = "Bob"  // 可以省略 this
        age = 30
    }
    println("Name: ${person.name}, Age: ${person.age}")
}

解释: 在 with 的 Lambda 表达式中,this 默认为 person,可以省略不写。

5. 匿名对象中的 this

在匿名对象中,this 指的是匿名对象本身。

val obj = object {
    val id = 1
    fun printId() {
        println("ID is: ${this.id}")
    }
}
fun main() {
    obj.printId() // 输出: ID is: 1
}

6. 接口和继承中的 this

在子类中,可以使用 this 调用当前类的属性或方法。要调用父类的属性或方法,可以使用 super。

open class Animal {
    open fun sound() {
        println("Animal sound")
    }
}

class Dog : Animal() {
    override fun sound() {
        println("Dog barks")
    }

    fun makeSound() {
        this.sound()  // 调用 Dog 的 sound 方法
        super.sound() // 调用父类的 sound 方法
    }
}
fun main() {
    val dog = Dog()
    dog.makeSound()
}

it 的用法

it 是 Lambda 表达式中单参数的隐式名称。如果 Lambda 只有一个参数且你没有明确指定参数名,Kotlin 会默认用 it 代表该参数。

1. Lambda 单参数的例子

val numbers = listOf(1, 2, 3, 4, 5)
val doubled = numbers.map { it * 2 }
println(doubled) // 输出: [2, 4, 6, 8, 10]

解释:
map 函数中的 Lambda 表达式有一个参数,代表当前元素。
it 指代集合中的每个元素,因此可以通过 it * 2 对其进行操作。

2. 高阶函数中的 it

fun calculate(operation: (Int) -> Int): Int {
    return operation(5)
}

fun main() {
    val result = calculate { it * it } // 传入 Lambda:5 * 5
    println(result) // 输出: 25
}

解释:
it 代表传给 Lambda 的参数(即 5)。
如果不需要自定义参数名,直接使用 it 可以让代码更简洁。

3. 自定义参数时不使用 it

你可以显式定义参数名,那么 it 就不会再使用:

val tripled = numbers.map { number -> number * 3 }
println(tripled) // 输出: [3, 6, 9, 12, 15]

解释: 这里用 number 代替了 it,提升了代码的可读性。

this 和 it 的区别

特性thisit
作用域引用当前对象或接收者对象。引用 Lambda 表达式中的单个参数。
使用场景类、对象、嵌套类、apply 等函数上下文。高阶函数、Lambda 表达式有一个参数时。
省略情况如果没有歧义,可以省略。如果 Lambda 表达式中没有指定参数名。
标签化用法可以使用标签化的 this@Outer。不能标签化,it 只能用于 Lambda 参数。
多参数情况不适用。不能使用,必须显式定义参数名。

this 和 it 的用法对比

1. 在 apply 中使用 this

class Person {
    var name: String = ""
    var age: Int = 0
}

fun main() {
    val person = Person().apply {
        this.name = "Alice"
        this.age = 25
    }
    println("Name: ${person.name}, Age: ${person.age}")
}

解释: apply 中的 this 是 Person 对象的接收者,可以省略写成 name = “Alice”。

2. 在 let 中使用 it

val name: String? = "Alice"
name?.let {
    println("Hello, $it!")
}

解释: 这里的 it 代表 name 的非空值 “Alice”。

3. 选择使用 this 还是 it 的场景

使用 this:当你在类或扩展函数中,操作的是当前对象(接收者)。
使用 it:当你在 Lambda 中有一个参数,并且不想明确命名时。

4. 结合使用 this 和 it

class Box(val label: String) {
    fun printLabel() {
        listOf("item1", "item2").forEach {
            println("$label contains $it")
        }
    }
}

fun main() {
    val box = Box("MyBox")
    box.printLabel()
}

解释:
this 引用 Box 类的当前对象,用于访问 label。
it 代表 forEach 中的元素。

5. 总结

this 主要用于引用当前对象或接收者对象,在类、apply 等上下文中频繁使用。
it 主要用于 Lambda 表达式的单个参数,是一种简洁的写法。
在实际开发中,如果需要频繁访问当前对象的成员,this 会更加合适;而在处理简单的 Lambda 表达式时,it 能让代码更加简洁。


http://www.kler.cn/a/371322.html

相关文章:

  • [vulnhub]Kioptrix: Level 1.2 (#3)
  • 5G RedCap工业路由器赋能电力物联网应用
  • WPF+MVVM案例实战(十一)- 环形进度条实现
  • Linux——常见指令及其权限理解(正在更新中)
  • mysql 十把锁之《小猫钓鱼》
  • apisix的原理及作用,跟spring cloud gateway有什么区别?
  • ffmpeg视频滤镜:膨胀操作-dilation
  • 算法:常见位运算技巧总结
  • Dirichlet分布生成联邦学生non-iid数据
  • css实现背景色的斑马条效果
  • 如何用李萨如图形测正弦信号的频率?若不使用李萨如图形,如何用示波器测交流信号频率?
  • PHP内存马:不死马
  • 微信小程序如何实现地图轨迹回放?
  • 地球上的中国:世界地图概览
  • Go中的泛型
  • NFS服务器作业
  • Linux云计算 |【第五阶段】CLOUD-DAY1
  • 字母象形与hand的不同解构
  • 【机器学习】揭秘XGboost:高效梯度提升算法的实践与应用
  • 「C/C++」C++ 设计模式 之 单例模式(Singleton)
  • 怎么实现电脑控制100台手机,苹果手机群控系统不用越狱实现新突破
  • GitHub Actions的 CI/CD
  • 鸿蒙开发培训要多久
  • 【计算机网络教程】课程 章节测试1 计算机网络概述
  • 启明云端乐鑫一级代理商,家电设备Matter交互方案,乐鑫ESP32-S3无线技术
  • JVM 调优深度剖析:优化 Java 应用的全方位攻略(一)