kotlin标准函数let apply等分析

在kotlin中,在standard.kt中定义了一些标准的方法,这里对这些方法进行挨个的阅读

TODO方法

这方法比较简单,就是直接抛出一个异常,这里有一个inline关键字,定义的是一个内联方法,内联方法的意思是调用时整个方法的代码一起替换过去,下面是TODO方法的源码

public inline fun TODO(): Nothing = throw NotImplementedError()
public inline fun TODO(reason: String): Nothing = throw NotImplementedError("An operation is not implemented: $reason")

 run方法

在看run方法时,我们先忽略掉contract方法来看,后面单独看contract,下面我把解释写在里面的代码中

总结:run方法接收一个block函数,并且在里面调用,并把block的返回值返回回来
@kotlin.internal.InlineOnly
//inline 内联函数
//<R> 定义的泛型R
//block: ()->R 参数名block, ()->R为block参数的类型, 是一个函数类型,函数没有参数,返回值是泛型类型的对象
//return block() 返回值是调用block函数返回的R对象
//总结:run方法接收一个block函数,并且在里面调用,并把block的返回值返回回来
public inline fun <R> run(block: () -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block() } @kotlin.internal.InlineOnly public inline fun <T, R> T.run(block: T.() -> R): R { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } return block() }

with方法:

总结:with方法接收一个T类型的receiver和一个T的扩展方法,返回在传入的receiver中调用的扩展方法的返回值

@kotlin.internal.InlineOnly
//inline 内联函数
//<T,R> 定义2个泛型T和R
//receiver: T 泛型类型T类型的参数receiver
//
block: T.()->R 函数类型的参数block,不过这个方法是通过扩展方法的方式定义的,这样在内部就可以拥有T的上下文
//return receiver.block() 返回值是调用T.block函数返回的R对象
//总结:with方法接收一个T类型的receiver和一个T的扩展方法,返回在传入的receiver中调用的扩展方法的返回值
public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
  contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
  return receiver.block()
}

apply方法

总结: apply方法是在T类型上面扩展的,接收的也是一个T类型的函数,作用是让block拥有T对象的上下文,并且返回T对象本身,这样在block中可以直接调用T里面的方法和属性

public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

 

also方法

总结:给T类型扩展一个also方法,这个方法也是执行block方法并返回T对象自身,和apply的区别只是把T作为参数传入

@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
//T.also 表示是T类型的扩展方法,
//block: (T)->Unit 参数是一个接收一个T对象参数的方法,没有返回值
public inline fun <T> T.also(block: (T) -> Unit): T { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } block(this) return this }

 

let方法

let方法与also方法比较相似,区别只是返回值不同,also是返回T对象本身,let是返回block返回的对象R

@kotlin.internal.InlineOnly
public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}

 

takeIf方法

takeIf根据predicate方法返回的是否是true来确定返回T对象本身还是返回null

public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (predicate(this)) this else null
}

 takeUnless方法

与takeIf相反,predicate是true,返回null

public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? {
    contract {
        callsInPlace(predicate, InvocationKind.EXACTLY_ONCE)
    }
    return if (!predicate(this)) this else null
}

 repeat方法

根据传入的times重复执行action times次

public inline fun repeat(times: Int, action: (Int) -> Unit) {
    contract { callsInPlace(action) }

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

  

 

posted @ 2024-07-15 15:49  coder木易  阅读(1)  评论(0编辑  收藏  举报