赞
踩
1.你工作这么些年,let内置标准函数一般用的很频繁吧,let的原理是什么?
答:
使用端的感受:
1.在使用的时候,任何的类型,都可以.let出来使用,这是为什么呢? 因为标准let内置函数内部对泛型进行了let函数扩展,意味着所有的类型都等于泛型,所以任何地方都是可以使用let函数的。
2.所有类型.let {} 其实是一个匿名的Lambda表达式,Lambda表达式的特点是,最后一行会自动被认为是返回值类型,所以在表达式返回Boolean,那么当前的let函数就是Boolean类型,以此类推。
fun main() {
val r1 = "Derry".let {
true
it.length
}
println(r1)
val r2 = 123.let {
999
"【${it}】"
}
println(r2)
}
根据上面分析的两点使用感受,来分析他的原理:
1.inline : 是因为函数有lambda表达式,属于高阶函数,高阶函数规范来说要加inline
2.<T, R> T.let : T代表是要为T而扩展出一个函数名let(任何类型都可以 万能类型.let), R代表是Lambda表达式最后一行返回的类型
3.block: (T) -> R : Lambda表达式名称block 输入参数是T本身 输出参数是R 也就是表达式最后一行返回推断的类型
4.: R { : R代表是Lambda表达式最后一行返回的类型,若表达式返回类型是Boolean, 那么这整个let函数的返回类型就是Boolean
// inline : 是因为函数有lambda表达式,属于高阶函数,高阶函数规范来说要加inline
// <T, R> T.let : T代表是要为T而扩展出一个函数名let(任何类型都可以 万能类型.let), R代表是Lambda表达式最后一行返回的类型
// block: (T) -> R : Lambda表达式名称block 输入参数是T本身 输出参数是R 也就是表达式最后一行返回推断的类型
// : R { : R代表是Lambda表达式最后一行返回的类型,若表达式返回类型是Boolean, 那么这整个let函数的返回类型就是Boolean
inline fun <T, R> T.let(block: (T) -> R): R {
println("你${this}.let在${System.currentTimeMillis()}这个时间点调用了我")
/*contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}*/
// 调用Lambda表达式
// 输入参数this == T == "Derry" / 123,
// 输出参数:用户返回String类型,就全部是返回String类型
return block(this)
}
总结:Kotlin内置标准let函数,运用了 高阶函数特性与Lambda,控制环节交给用户完成,用户在自己的Lambda表达式中,若返回Boolean,整个let函数 与 Lambda返回 都全部是Boolean
为了保证所有的类型都能正常使用let,给泛型增加了扩展函数let,所以所有的地方都可以使用let函数。
1.你工作这么些年,Kotlin语言提供的高阶run函数一般用的很频繁吧,run的原理是什么?
答:
run在Kotlin语法中使用端的感受:
1.在使用的时候,任何的类型,都可以.run出来使用,这是为什么呢? 因为标准run内置函数内部对泛型进行run函数扩展,意味着所有的类型都等于泛型,所以任何地方都是可以使用run函数的。
2.所有类型.run{} 其实是一个匿名的Lambda表达式,Lambda表达式的特点是,最后一行会自动被认为是返回值类型,例如在表达式返回Boolean,那么当前的run函数就是Boolean类型,例如在表达式返回Int类型,那么当前的run函数就是Int类型,以此类推。
fun main() {
val r1 : Int = "Derry".run {
true
length
}
println(r1)
val r2 : String = 123.run {
999
"【${it}】"
}
println(r2)
}
根据上面分析的两点使用感受,来分析他的原理:
1.inline : 是因为函数有lambda表达式,属于高阶函数,高阶函数规范来说要加inline
2.<T, R> T.run : T代表是要为T而扩展出一个函数名run(任何类型都可以 万能类型.run), R代表是Lambda表达式最后一行返回的类型
3.block: T.() -> R : Lambda表达式名称block 输入参数是T本身 输出参数是R 也就是表达式最后一行返回推断的类型
4.: R { : R代表是Lambda表达式最后一行返回的类型,若表达式返回类型是Boolean, 那么这整个run函数的返回类型就是Boolean
5.T.() 是让lambda表达式里面持有了this(run函数), (T) 是让lambda表达式里面持有了it(let函数)
/* 1.inline : 是因为函数有lambda表达式,属于高阶函数,高阶函数规范来说要加inline 2.<T, R> T.run : T代表是要为T而扩展出一个函数名run(任何类型都可以 万能类型.run), R代表是Lambda表达式最后一行返回的类型 3.block: T.() -> R : Lambda表达式名称block 输入参数是T本身 输出参数是R 也就是表达式最后一行返回推断的类型 4.: R { : R代表是Lambda表达式最后一行返回的类型,若表达式返回类型是Boolean, 那么这整个run函数的返回类型就是Boolean 5.T.() 是让lambda表达式里面持有了this(run函数), (T) 是让lambda表达式里面持有了it(let函数) */ public inline fun <T, R> T.run(block: T.() -> R): R { println("你${this}.run在${System.currentTimeMillis()}这个时间点调用了我") /*contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }*/ // 调用Lambda表达式 // 输入参数this == T == "Derry" / 123, // 输出参数:用户返回String类型,就全部是返回String类型 return block() }
总结:Kotlin内置标准run函数,运用了 高阶函数特性与Lambda,控制环节交给用户完成,用户在自己的Lambda表达式中,若返回Boolean,整个run函数 与 Lambda返回 都全部是Boolean
为了保证所有的类型都能正常使用run,给泛型增加了扩展函数run,所以所有的地方都可以使用run函数。
我整理了一套Android面试题合集,除了以上面试题,还包含【Java 基础、集合、多线程、虚拟机、反射、泛型、并发编程、Android四大组件、异步任务和消息机制、UI绘制、性能调优、SDN、第三方框架、设计模式、Kotlin、计算机网络、系统启动流程、Handler、Binder、AMS、Dart、Flutter、算法和数据结构、NDK、H.264、H.265.音频编解码、FFmpeg、OpenMax、OpenCV、OpenGL ES】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。