Kotlin 高阶函数进阶

围巾🧣 2024年05月17日 341次浏览

函数类型定义

// () -> Unit    空参函数  并且 没有返回值  函数名=method01

// TODO 定义没有问题,调用不行
var method01 : () -> Unit
method01() // 不能调用  没有具体的实现

var method02 : (Int, Int) -> Int
method02(9, 9)

var method03: (String, Double) -> Any?
method03("心兰相随", 543354.4)

var method04 : (Int, Double, Long, String ? ) -> Boolean
method04(1, 545, 3543, null)

var method05 : (Int, Int) -> Int
method05(9, 9)

// : (形参类型)
// = {具体详情}

实现 + 调用

// TODO 定义没有问题,调用OK ,因为有实现了
var m06 : (Int, Int) -> Int = {number1, number2 -> number1 + number2}
println("m06:${m06(9, 9)}")

var m07 = { number1: Int , number2: Int -> number1.toDouble() + number2.toDouble()}
println("m07:${m07(100, 100)}")

var m08 : (String, String) -> Unit = {aString, bString -> println("a:$aString,  b:$bString")}
m08("李元霸", "王五")

var m09 : (String) -> String = {str -> str}
println("m09:${m09("降龙十八掌")}")

var m10 : (Int) -> Unit = {
    when(it) {
        1 -> println("你是一")
        in 20..30 -> println("你是 二十 到 三十")
        else -> println("其他的数字")
    }
}
m10(29)

var m11 : (Int, Int, Int) -> Unit = { n1, n2, n3 ->
    println("n1:$n1, n2:$n2, n3:$n3")
}
m11(29,22,33)

var m12 = { println("我就是m12函数,我就是我") }
m12()

val m13 = {sex: Char -> if (sex == 'M') "代表是男的" else "代表是女的"}
println("m13:${m13('M')}")

// 覆盖操作
var m14 = {number: Int -> println("我就是m14  我的值: $number")}
m14 = {println("覆盖  我的值: $it")}
m14(99)

// 需求:我想打印, 并且,我还想返回值,就是 我什么都想要
var m15 = { number: Int -> println("我想打印: $number")
    number + 1000000
}
println("m15:${m15(88)}")

// --------------
// 对外暴漏
fun loginEngine(userName: String, userPwd: String) : Unit {

    // 使用高阶  {},一个参数默认叫 it
    loginService(userName, userPwd) { name, pwd ->
        if (name == "心兰相随" && pwd == "123456") {
            println("恭喜:${name}登录成功")
        } else {
            println("登录失败,请检查 用户名 或 密码....!!")
        }
    }
}

// 标准  String String --> Unit
typealias RequestLogin = (String, String) -> Unit

private fun loginService(userName: String, userPwd: String, requestLogin: RequestLogin) : Unit {
    requestLogin(userName, userPwd)
}
// 再次模拟登录流程
loginEngine("心兰相随", "123456") {
    if (it) println("最终得到的结果是 登录成功") else println("最终得到的结果是 登录失败")
}

// 内部去完成登录功能
private fun loginEngine(userName: String, userPwd: String,   responseResult: (Boolean)-> Unit) {
    val DB_USER_NAME = "心兰相随"
    val DB_USER_PWD = "123456"

    if (userName == DB_USER_NAME && userPwd == DB_USER_PWD) {
        // TODO 模拟做了很多业务逻辑
        //  ......
        responseResult(true)
    } else {
        // TODO 模拟做了很多业务逻辑
        //  ......
        responseResult(false)
    }
}

泛型高阶函数

定义 + 调用

// TODO m: T.() -> R
// T.() == 给T来一个匿名函数
fun <T, R> T.myRun(m: () -> R): R = m()  // 调用高阶函数

// 普通函数
fun <T, R> myWith(input: T, mm: T.() -> R): R {
    return input.mm() // this
}

// T.() 给高阶函数提供 this
// (T)  给高阶函数提供 it
fun <T, R> T.myLet(mm: T.(T) -> R): R {
    // T == this   () -> R
    // mm(this) == this     vs    T.(T)  -> R
    return mm(this)
}

// 控制器 如果你是true,我就执行你,否则不执行
inline fun onRun(isRun: Boolean, mm: () -> Unit) {
    if (isRun) mm()
}


fun main() {

    name.let { }

    // r == 外面那个R
    val r = common().myRun {
        println("AAAA")
        true
        433535.45345

        '男'
        "AAAA"  // == 里面的R泛型
    }

    myWith(name) {
        length
    }

    name.myLet {
        length
        length
    }

    onRun(true) {
        println("执行了..")
    }

    onRun(true, {
        println("执行了222")
    })

    val runValue = Runnable {
        println("我就是Runnabler任务")
    }

    onRun(true, runValue::run)
}

定义 + 调用

fun main() {
    commonOk().myRunOk {
        true
    }

    nameS.myRunOk {
        false
    }

    val booResult = nameS.myRunOk2 {
        false
    }
}

// T.() 给万能类型 增加 匿名函数        只不过这个匿名函数 在 高阶函数中
// () 就是高阶函数

// 给 ”万能类型“ 类型 增加了扩展函数  一增加   方法.myRunOk
fun <万能类型> 万能类型.myRunOk(mm: 万能类型.() -> Boolean) {
    mm() // 执行高阶
}

// 给 ”万能类型“ 类型 增加了扩展函数  一增加   方法.myRunOk2
fun <万能类型, 最终类型> 万能类型.myRunOk2(mm: 万能类型.(万能类型) -> 最终类型): 最终类型 {
    return mm(this) // 执行高阶
}

apply run let 实现

public inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}

public inline fun <T> T.also(block: (T) -> Unit): T {
    block(this)
    return this
}

public inline fun <T, R> T.let(block: (T) -> R): R {
    return block(this)
}

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

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