kotlin范围函数(let,run,apply,also,with)

本文介绍了Kotlin标准库中的范围函数,包括let、run、with、apply和also等。阐述了使用这些函数的简单判断规则,如返回自身可从apply和also中选等。还分别说明了各函数的功能,如let可通过it指代对象等,并给出了简单举例。

版权声明:本文为延成原创文章,转载请标明出处

学习kotlin可直接查看Kotlin官方文档,既方便又实用

范围功能

  • Kotlin标准库包含几个函数,其唯一目的是在对象的上下文中执行代码块。当您在提供了lambda表达式的对象上调用此类函数时,它会形成一个临时范围。在此范围内,您可以在不使用其名称的情况下访问该对象。这些函数称为范围函数。有5个:let,run,with,apply,和also。

使⽤时可以通过简单的规则作出⼀些判断:

  • 返回⾃身 -> 从 apply 和 also 中选
    • 作⽤域中使⽤ this 作为参数 ----> 选择 apply
    • 作⽤域中使⽤ it 作为参数 ----> 选择 also
  • 不需要返回⾃身 -> 从 run 和 let 中选择
    • 作⽤域中使⽤ this 作为参数 ----> 选择 run
    • 作⽤域中使⽤ it 作为参数 ----> 选择 let
  • apply 适合对⼀个对象做附加操作的时候
  • let 适合配合空判断的时候 (最好是成员变量,⽽不是局部变量,局部变量更适合
    ⽤ if )
  • with 适合对同⼀个对象进⾏多次操作的时候

.let

  • 功能:在函数块内可以通过 it 指代该对象。返回值为函数块的最后一行或指定return表达式。
	val alice = Person("Alice", 20, "Amsterdam")
	alice.moveTo("London")
	alice.incrementAge()
	println(alice)
	
	Person("Alice", 20, "Amsterdam").let {
	    it.moveTo("London")
	    it.incrementAge()
	    println(it)
	}

	//1.
	val numbers = mutableListOf("one", "two", "three", "four", "five")
	val resultList = numbers.map { it.length }.filter { it > 3 }
	println(resultList)  
	//[5, 4, 4]

	//2.
	val numbers = mutableListOf("one", "two", "three", "four", "five")
	numbers.map { it.length }.filter { it > 3 }.let { 
	    println(it)
	    // and more function calls if needed
	} 
	//[5, 4, 4]

	//3.
	val numbers = mutableListOf("one", "two", "three", "four", "five")
	numbers.map { it.length }.filter { it > 3 }.let(::println)
	//[5, 4, 4]

.run

  • 功能:调用run函数块。返回值为函数块最后一行,或者指定return表达式。

    // this
    str.run {
        println("The receiver string length: $length")
        //println("The receiver string length: ${this.length}") // does the same
}

run函数和apply区别:run函数是使用最后一行的返回,apply返回当前自己的对象。

.apply

  • 功能:调用某对象的apply函数,在函数块内可以通过 this 指代该对象。返回值为该对象自己。
 		// same as this.age = 20 or adam.age = 20
		val adam = Person("Adam").apply { 
	    age = 20                      
	    city = "London"
	}

.also

功能:调用某对象的also函数,则该对象为函数的参数。在函数块内可以通过 it 指代该对象。返回值为该对象自己。

		
	fun getRandomInt(): Int {
	    return Random.nextInt(100).also {
	        writeToLog("getRandomInt() generated value $it")
	    }
	}

	//.also自定义名称
	fun getRandomInt(): Int {
	    return Random.nextInt(100).also { value ->
	            writeToLog("getRandomInt() generated value $value")
	    }
	}

with

功能:它是将某对象作为函数的参数,在函数块内可以通过 this 指代该对象。返回值为函数块的最后一行或指定return表达式。

		
	val numbers = mutableListOf("one", "two", "three")
	with(numbers) {
	    val firstItem = first()
	    val lastItem = last()        
	    println("First item: $firstItem, last item: $lastItem")
	}
	//First item: one, last item: three

repeat

功能:循环执行多少次block中内容。

		
fun main(args: Array<String>) {
 repeat(3) {
      println("Hello world")
  }
}

运行结果:
Hello world
Hello world
Hello world

takeIf

功能:满足block中条件,则返回当前值,否则返回null,block的返回值Boolean类型

		
fun main(args: Array<String>) {
    val date = Date().takeIf {
        // 是否在2018年元旦后
        it.after(Date(2018 - 1900, 0, 1))
    }

    println("date = $date")
}

// 运行结果
// date = Thu Jan 04 19:42:09 CST 2018

takeIf

和takeIf相反,如不满足block中的条件,则返回当前对象,否则为null

简单举例

定义一个实体类

class User {
    var id: Int = 0
    var name: String? = null
    var hobbies: List<String>? = null

    override fun toString(): String {
        return "User(id=$id, name=$name, hobbies=$hobbies)"
    }
}

普通的赋值语句这样就可以了

var user = User()
user.id = 1
user.name = "test1"
user.hobbies = listOf("aa", "bb", "cc")
println("user = $user")

如果使用let,apply,run,with可以这样,let和also是需要it的,其他的默认使用this

user.let {
    it.id = 2
    it.name = "test2"
    it.hobbies = listOf("aa", "bb", "cc")
}
println("user = $user")

user.also {
    it.id = 3
    it.name = "test3"
    it.hobbies = listOf("aa", "bb", "cc")
}
println("user = $user")

user.apply {
    id = 2
    name = "test2"
    hobbies = listOf("aa", "bb", "cc")
    Date()
}
println("user = $user")

user.run {
    id = 3
    name = "test3"
    hobbies = listOf("aa", "bb", "cc")
    Date()
}
println("user = $user")

with(user) {
    id = 4
    name = "test4"
    hobbies = listOf("aa", "bb", "cc")
    Date()
}
println("user = $user")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值