天天看點

Kotlin高階函數之with,let,apply,run

    上一篇文章中介紹了RecycleView的Kotlin程式設計,在建立ViewHolder的時候有這麼一段代碼:

class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bind(forecast: Forecast) {
            itemView.tv_text1.text = forecast.date
            itemView.tv_text2.text = forecast.high
            itemView.tv_text3.text = forecast.low
            itemView.tv_text4.text = forecast.notice
        }
    }
           

    這篇文章将使用Kotlin高階函數with,let,apply,run對其演化,來說明這幾個函數的用法和差別。

with函數

    with函數傳入對象可以直接調用對象的方法,傳回是最後一行。

public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
        contract {
            callsInPlace(block, InvocationKind.EXACTLY_ONCE)
        }
        return receiver.block()
    }
           

    例如:with裡面傳入itemView對象,調用itemView的tv_text1,tv_text2……等方法,傳回Unit類型資料。

fun bind(forecast: Forecast) = with(itemView) {
                tv_text1.text = forecast.date
                tv_text2.text = forecast.high
                tv_text3.text = forecast.low
                tv_text4.text = forecast.notice
                setOnClickListener { itemClick(forecast) }
    }
           

apply函數

    調用某對象的apply函數,在函數範圍内,可以任意調用該對象的任意方法,并傳回該對象。

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

    例如:調用itemClick(forecast)對象的apply方法,并且傳回itemClick(forecast)對象,他沒有傳回值,傳回Unit。

fun bind(forecast: Forecast) = itemClick(forecast).apply {
        itemView.tv_text1.text = forecast.date
        itemView.tv_text2.text = forecast.high
        itemView.tv_text3.text = forecast.low
        itemView.tv_text4.text = forecast.notice
        itemView.setOnClickListener { itemClick(forecast) }
    }
           

let函數

    預設目前這個對象作為閉包的it參數,傳回值是函數裡面最後一行,或者指定return。

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

    例如:調用itemView的let方法,把itemView對象作為it使用,傳回Unit。

fun bind(forecast: Forecast) = itemView.let {
        it.tv_text1.text = forecast.date
        it.tv_text2.text = forecast.high
        it.tv_text3.text = forecast.low
        it.tv_text4.text = forecast.notice
        it.setOnClickListener { itemClick(forecast) }
    }
           

run函數

    調用指定的函數塊,傳回最後一行或者return相關内容。

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

    例如:

fun bind(forecast: Forecast) = run {
        itemView.tv_text1.text = forecast.date
        itemView.tv_text2.text = forecast.high
        itemView.tv_text3.text = forecast.low
        itemView.tv_text4.text = forecast.notice
        itemView.setOnClickListener { itemClick(forecast) }
    }
           

繼續閱讀