Kotlin StandardKt

2021-11-24 14:04:57 浏览数 (1)

==TODO== 往往出现在子类实现抽象父类时被重写的抽象方法内,如果方法不重写就必须将 TODO 去除,否则会抛出异常

代码语言:javascript复制
// Always throws NotImplementedError stating that operation is not implemented.
@kotlin.internal.InlineOnly
public inline fun TODO(): Nothing = throw NotImplementedError()

/**
 * Always throws [NotImplementedError] stating that operation is not implemented.
 *
 * @param reason a string explaining why the implementation is missing.
 */
@kotlin.internal.InlineOnly
public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An operation is not implemented: $reason")

==run== 是一个作用域函数,run{} 看起来和直接执行函数没有任何区别,确实如此,不过它的最大作用就是作用域,在函数内修改的值不会影响到外部。T.run{} 则是在其函数体内部的 this = T

代码语言:javascript复制
/**
 * Calls the specified function [block] and returns its result.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#run).
 */
@kotlin.internal.InlineOnly
public inline fun <R> run(block: () -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

/**
 * Calls the specified function [block] with `this` value as its receiver and returns its result.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#run).
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

==with== 该函数从实现上看是把实例及其函数作为参数传递进去并只执行一次,作用和 T.run{} 几乎一样,除了传递的参数,返回值和执行的效果都是一样的,在实际开发的运用场景如下

代码语言:javascript复制
// 常规写法
var paint = Paint()
paint.color = Color.BLACK
paint.strokeWidth = 1.6f
paint.textSize = 16.0f
paint.isAntiAlias = true

// run 写法
paint.run {
    color = Color.BLACK
    strokeWidth = 1.6f
    textSize = 16.0f
    isAntiAlias = true
}

// with 写法
with(paint){
    color = Color.BLACK
    strokeWidth = 1.6f
    textSize = 16.0f
    isAntiAlias = true
}
代码语言:javascript复制
/**
 * Calls the specified function [block] with the given [receiver] as its receiver and returns its result.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#with).
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}

==apply== T.apply{} 和 T.run{} 唯一的区别就是返回值,T.run{} 返回 block 函数参数的返回值,T.apply{} 返回 T 本身

代码语言:javascript复制
/**
 * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#apply).
 */
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

T.apply{} 具体运用场景如下

代码语言:javascript复制
var list = mutableListOf<String>().apply {
    add("A")
    add("B")
    add("C")
}

==also== block 函数内部用 it 来引用 T,最终返回 T 本身

代码语言:javascript复制
/**
 * Calls the specified function [block] with `this` value as its argument and returns `this` value.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#also).
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.also(block: (T) -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block(this)
    return this
}

==let== T.let{} 和 T.also{} 有点类似,区别在与 also 返回的是 T 本身,而 let 返回是 block 函数的执行结果

代码语言:javascript复制
/**
 * Calls the specified function [block] with `this` value as its argument and returns its result.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#let).
 */
@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}

==takeIf== T.takeIf{} 在 predicate 函数执行为 true 时返回本身,否则为 null,它可以解决 if 语句,具体运用场景如下

代码语言:javascript复制
fun main() {
    val str = "abcdefghijklmn"
    str.indexOf("X").takeIf {
        println("it=$it")
        it >= 0
    }?.let {
        println("str 中包含该字符")
    }?:run{
        println("str 中不包含该字符")
    }
}

// logcat 执行如下
it=-1
str 中不包含该字符

if 都看得懂,但是 takeIf、let、run 需要学,这样写的好处在于简化写法、逻辑清晰、代码精简和优雅(装逼必备),takeUnless 和 takeIf 逻辑相反,不再探讨用法

代码语言:javascript复制
/**
 * Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#takeif-and-takeunless).
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (predicate(this)) this else null
}

/**
 * Returns `this` value if it _does not_ satisfy the given [predicate] or `null`, if it does.
 *
 * For detailed usage information see the documentation for [scope functions](https://kotlinlang.org/docs/reference/scope-functions.html#takeif-and-takeunless).
 */
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (!predicate(this)) this else null
}

==repeat== 等价与 for 循环和 forEach, repeat(10) 代表从 0 至 9 循环 10 次

代码语言:javascript复制
/**
 * Executes the given function [action] specified number of [times].
 *
 * A zero-based index of current iteration is passed as a parameter to [action].
 *
 * @sample samples.misc.ControlFlow.repeat
 */
@kotlin.internal.InlineOnly
public inline fun repeat(times: Int, action: (Int) -> Unit) {
    contract { callsInPlace(action) }

    for (index in 0 until times) {
        action(index)
    }
}

最后总结一下,run 等价于 let ,返回值为函数最后一行或者return指定的表达式;apply 等价于 also,返回值为本对象。唯一的区别就是 this 和 it 来获取当前被扩展的实例

0 人点赞