Kotlin:Lambda
Posted wzj_what_why_how
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin:Lambda相关的知识,希望对你有一定的参考价值。
/**
* 1.6.1 let
*/
//上下文对象用it引用,返回Lambda返回的值。
//let()用在调用链的最后面,能省点事,比如:
fun main() {
val numbers = mutableListOf<String>("one", "tow", "three", "four")
val resultList = numbers.map { it.length }.filter { it > 3 }
println(resultList)
}
//改成let后
fun main1() {
val numbers = mutableListOf<String>("one", "tow", "three", "four")
val resultList = numbers.map { it.length }.filter { it > 3 }.let { println(it) }
}
fun main2() {
//还有一种用法,就是判断对象是否为空,如果不为空,则执行Lambda中的代码,并将其上下文对象自动变成不可为空类型。示例如下:
val str: String? = "Hello"
//processNonNullString(str) //--这样调用有错误,因为函数要求参数不可为空,而str可为空
//正确做法:
val length = str?.let {
print("let() called on $it")
processNonNullString(it) //这样调用OK:“it” 以自动变为不可为空
it.length
}
}
fun processNonNullString(str: String) {}
//在let中一般放置相关性比较大的对上下文对象的一堆操作,包括设置属性的值、调用方法并对返回值进行运算等。
/**
* 1.6.2 run()
*/
//上下文对象用this引用,返回Lambda返回回的值
//run的作用有点像let,把对上下文对象相关性比较大的操作放在一起。run和let可以很自然地相互替换,比如:
class MultiporService(val url: String, val param: Int){
var port: Int = 8888
fun query(str: String){}
fun prepareRequest(): String {return "abc"}
}
val service = MultiporService("https://google.com", 80)
val result = service.run {
port = 8080
query( "${prepareRequest()} to port $port")
}
val letResult = service.let {
it.port = 8080
it.query("${it.prepareRequest()} to port ${it.port}")
}
//run 可以不在某个对象上调用,此时它的作用是将一堆相关的操作放在一起。当然也可以产生结果并返回给某个变量以保存下来,比如:
val hexNumberRegex = run {
val digits = "0-9"
val hexDigits = "A-Fa-f"
val sign = "+-"
Regex("s$sign]?[$digits$hexDigits]+")
}
fun testHexNumberRegex(){
for (match in hexNumberRegex.findAll("+1234 -FFFF not-a-number")){
println(match.value)
}
}
//注意,hexNumberRegex是一个常量,保存了runzhong Regex()返回的值。
/**
* 1.6.3 apply()
*/
//上下文对象用this引用,返回上下文对象。
//在此函数Lambda中,主要对上下文对象的属性进行设置,意图是“将这些参数应用到这个对象”,所以一般用于配置对象时。
//看下面的示例代码:
val adam = KotlinBaseKnowledge.Person("Adam").apply {
age = 32
city = "London"
}
/**
* 1.6.4 also()
*/
//上下文对象用it引用,返回上下文对象。
//此函数一般用于调用那些以上下文对象为参数的方法,比如打印上下文对象的属性值,
// 或者将上下文对象的属性值记入日志中,而且不应该在Lambda中更改上下文对象,比如:
fun main3() {
val numbers = mutableListOf<String>("one", "tow", "three", "four")
numbers.also { println(it) }.add("five")
}
//使用also的特点是,如果从调用链中抽走also调用,不会影响调用逻辑和执行结果。
/**
* 1.6.5 with()
*/
//上下文对象用this引用,返回Lambda返回的值。
//with的作用可以理解为“用这个对象,做点事”。当前面的函数都不大合适时,就可以考虑它了,比如:
fun main4() {
val numbers = mutableListOf<String>("one", "tow", "three", "four")
val firstrAndLast = with(numbers){
"The first element is ${this[0]} ; The Last element is ${this[this.lastIndex]}"
}.let { println(it) }
}
//在lanmbda中引用上下文对象时,有的用this,有的用it。run、with、apply用this,this可以省略!
//在返回值方面,apply和also返回的是上下文对象,let,run, with返回的是Lambda中返回的值。
//1.it
//我们知道,用lambda表达式,我们可以把一些函数的写法简化成“输入参数->(运算)输出”,其中,如果只有一个参数时,写出来的代码就像是
//val dints=ints.map{value->value*2}
//对于这种单个参数的运算式,可以进一步简化,把参数声明和->都简化掉,只保留运算输出,不过这要用it来统一代替参数,代码就变成
//val dints2=ints.map{ it*2}
//这就是it的用法,进一步简化单参数的lambda表达式。
//2.let
//let能把更复杂的对象赋给it,比如
//File("a.text").let{
// it.absoluteFile //let把file对象赋给了it
//}
//这个特性可以稍微扩展一下,比如增加?检查
//getVaraiable()?.let{
// it.length // when not null
//}
//这样可以先检查返回值是否为空,不为空才继续进行
//3.apply
//apply可以操作一个对象的任意函数,再结合let返回该对象,例如
//ints.apply{//拿到一个arraylist对象
// add(0,3) //操作该对象的函数
//}.let{ it.size} // 返回该对象(已被修改),继续处理
//4.run
//apply是操作一个对象,run则是操作一块儿代码
//apply返回操作的对象,run的返回则是最后一行代码的对象
//ints.run(){ //操作一个集合
//add(0,3) //操作该集合
//var a=Activity()
//a //会返回最后一行的对象
//}.let{ it.actionBar}
//5.with
//with有点儿像apply,也是操作一个对象,不过它是用函数方式,把对象作为参数传入with函数,然后在代码块中操作,例如
//with(ints){ //传入一个集合
// add(0,3) //操作该集合
// var a=Activity()
// a //会返回最后一行的对象
//}.let{ it.actionBar}
//但是返回像run,也是最后一行
//6.inline
//inline内联函数,其实相当于对代码块的一个标记,这个代码块将在编译时被放进代码的内部,
// 相当于说,内联函数在编译后就被打散到调用它的函数里的,目的是得到一些性能上的优势。
以上是关于Kotlin:Lambda的主要内容,如果未能解决你的问题,请参考以下文章