目次

標準関数・スコープ関数

apply

レシーバーに対して一連の関数を呼びだすことでレシーバーに対する設定ができる。

// 定義
public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}
// サンプル
    val file= File("text.txt").apply {
        setReadable(true)
        setWritable(true)
        setExecutable(true)
    }

let

渡されたラムダにitで参照できるようにする。

// 定義
public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}
// サンプル
    val value = listOf<Int>(1,2,3).shuffled().first().let { it*it }
    println(value)
 
// null合体演算子との組み合わせ
関数 渡し 関数コール 返し
apply 何も渡さない 相対スコープ レシーバー
let レシーバーをラムダに渡す ラムダの最後の行
run 相対スコープ ラムダの最後の行

run

applyと同じく関数は相対スコープで呼び出されるが、何も返さない。
runを使った呼び出しの連鎖のほうがネストしているよりわかりやすい。

fun nameIsLong(name:String) = name.length > 10
fun playerCreateMessage(nameTooLong:Boolean):String{
    return if (nameTooLong){
        "too long"
    }else{
        "welcome!!"
    }
}

fun main(){
    // runによる関数呼び出しの連鎖
    val text = "polarcubis,supreme master5 of nyethack"
        .run(::nameIsLong) // >>> true
        .run(::playerCreateMessage) // >>> too long
        .run(::print)
}
}
>>> too long

with

引数を第一パラメーターとして受け取る必要がある。
可能ならばrunで置き換える。

also

let とにているが、letはラムダの結果を返す。
alsoはレシーバーを返す。

takeif

真だとレシーバーを返す。
偽だとnullを返す

takeUnless

偽だとレシーバーを返す。
真だとnullを返す。
わかりにくいため使用すべきではない。