此函数的作用:显示抛出NotImplementedError错误。NotImplementedError错误类继承至Java中的Error
public class NotImplementedError(message: String = "An operation is not implemented.") : Error(message)
//TODO的源码
@kotlin.internal.InlineOnly
public inline fun TODO(): Nothing = throw NotImplementedError()
@kotlin.internal.InlineOnly
public inline fun TODO(reason: String): Nothing =
throw NotImplementedError("An operation is not implemented: $reason")
//使用
fun main(args: Array) {
TODO("测试TODO函数,是否显示抛出错误")
}
调用todo,如果不传参的话,就会报An operation is not implemented.
//源码
public inline fun run(block: () -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
val index = 3
val num = run {
when(index){
0 -> "kotlin"
1 -> "java"
2 -> "php"
3 -> "javaScript"
else -> "none"
}
}.length
println("num = $num")
//输出结果为 num = 10
public inline fun T.run(block: T.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block()
}
val str = "kotlin"
str.run {
println( "length = ${this.length}" )
println( "first = ${first()}")
println( "last = ${last()}" )
}
//输出结果为:
length = 6
first = k
last = n
在其中,可以使用this关键字,因为在这里它就代码str这个对象,也可以省略。因为在源码中我们就可以看出,block()就是一个T类型的扩展函数。
在实际开发中,我们可以:
val mTvBtn = findViewById(R.id.text)
mTvBtn.run{
text = "kotlin"
textSize = 13sp
...
}
其实with() 函数和T.run()函数的作用是相同的,只是前者是高阶函数,后者是扩展的高阶函数
val str = "kotlin"
with(str) {
println( "length = ${this.length}" )
println( "first = ${first()}")
println( "last = ${last()}" )
}
//其输出结果为:
length = 6
first = k
last = n
如果输出对象为null?,其写法不同之处
val newStr : String? = "kotlin"
with(newStr){
println( "length = ${this?.length}" )
println( "first = ${this?.first()}")
println( "last = ${this?.last()}" )
}
newStr?.run { //更优雅啊
println( "length = $length" )
println( "first = ${first()}")
println( "last = ${last()}" )
}
public inline fun T.apply(block: T.() -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return this
}
从T.apply()源码中在结合前面提到的T.run()函数的源码我们可以得出,这两个函数的逻辑差不多,唯一的区别是T,apply执行完了block()函数后,返回了自身对象。而T.run是返回了执行的结果。
故而: T.apply的作用除了实现能实现T.run函数的作用外,还可以后续的再对此操作。下面我们看一个例子:
例:为TextView设置属性后,再设置点击事件等
val mTvBtn = findViewById(R.id.text)
mTvBtn.apply{
text = "kotlin"
textSize = 13f
...
}.apply{
// 这里可以继续去设置属性或一些TextView的其他一些操作
}.apply{
setOnClickListener{ .... }
}
或者:设置为Fragment设置数据传递
// 原始方法
fun newInstance(id : Int , name : String , age : Int) : MimeFragment{
val fragment = MimeFragment()
fragment.arguments.putInt("id",id)
fragment.arguments.putString("name",name)
fragment.arguments.putInt("age",age)
return fragment
}
// 改进方法
fun newInstance(id : Int , name : String , age : Int) = MimeFragment().apply {
arguments.putInt("id",id)
arguments.putString("name",name)
arguments.putInt("age",age)
}
public inline fun T.also(block: (T) -> Unit): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block(this)
return this
}
跟apply()几乎一模一样,不同的是,also只能用it调用自身而apply使用this
"kotlin".also {
println("结果:${it.plus("-java")}")
}.also {
println("结果:${it.plus("-php")}")
}
"kotlin".apply {
println("结果:${this.plus("-java")}")
}.apply {
println("结果:${this.plus("-php")}")
}
public inline fun T.let(block: (T) -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return block(this)
}
let可以规避空指针,实现空安全;另外其与also和apply的不同,如下:
"kotlin".let {
println("原字符串:$it") // kotlin
it.reversed()
}.let {
println("反转字符串后的值:$it") // niltok
it.plus("-java")
}.let {
println("新的字符串:$it") // niltok-java
}
"kotlin".also {
println("原字符串:$it") // kotlin
it.reversed()
}.also {
println("反转字符串后的值:$it") // kotlin
it.plus("-java")
}.also {
println("新的字符串:$it") // kotlin
}
"kotlin".apply {
println("原字符串:$this") // kotlin
this.reversed()
}.apply {
println("反转字符串后的值:$this") // kotlin
this.plus("-java")
}.apply {
println("新的字符串:$this") // kotlin
}
public inline fun T.takeIf(predicate: (T) -> Boolean): T? {
contract {
callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
}
return if (predicate(this)) this else null
}
从源码可以看出,这是一个关于条件判断的函数:传入一个你希望的一个条件,如果对象符合你的条件则返回自身,反之,则返回null
val str = "kotlin"
val result = str.takeIf {
it.startsWith("ko")
}
println("result = $result") //kotlin
public inline fun T.takeUnless(predicate: (T) -> Boolean): T? {
contract {
callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
}
return if (!predicate(this)) this else null
}
跟takeif恰好相反:传入一个你希望的一个条件,如果对象符合你的条件则返回null,反之,则返回自身。
val str = "kotlin"
val result = str.takeUnless {
it.startsWith("ko")
}
println("result = $result") // null
public inline fun repeat(times: Int, action: (Int) -> Unit) {
contract { callsInPlace(action) }
for (index in 0..times - 1) {
action(index)
}
}
repeat(5){
println("我是重复的第${it + 1}次,我的索引为:$it")
}
输出结果为:
我是重复的第1次,我的索引为:0
我是重复的第2次,我的索引为:1
我是重复的第3次,我的索引为:2
我是重复的第4次,我的索引为:3
我是重复的第5次,我的索引为:4
顾名思义其用作延时,延迟初始化即:指当程序在第一次使用到这个变量(属性)的时候在初始化。
// 声明一个延迟初始化的字符串数组变量
private val mTitles : Array by lazy {
arrayOf(
ctx.getString(R.string.tab_title_android),
ctx.getString(R.string.tab_title_ios),
ctx.getString(R.string.tab_title_h5)
)
}
// 声明一个延迟初始化的字符串
private val mStr : String by lazy{
"我是延迟初始化字符串变量"
}
再详细的,大家可以参考这里