Lambda 之 JAVA & Kotlin 中二问题

先附上整理学习的kotlin Lambda表达式范例

package main.class_7

import main.tools.KtTools

fun main(args: Array<String>) {

    val dog = Dog()

//注! lambda 需要 被 {} 包裹

    //最原始的写法
    dog.run(10, 100, { t, d -> d / t })

    //当表达式 为方法最后一个参数时 可以将 表达式写在最外面
    dog.run(5, 20) { t, d -> d / t }

    //表达式 无返回值,可以直接在表达式中 添加其他的执行语句
    dog.bark("中华田园犬") { name -> KtTools.p("$name 在狂吠") }

    //方法无参数 表达式 无参数 但有返回值,所以这里 {}内 最后一行需要给出返回值 String
    dog.slowRun {
        val str = "小土狗在 慢跑"
        str
    }

    //除动态 添加表达式外 还可以直接声明好 lambda 表达式
    dog.jump(40, 5, calculateAbility)
}


class Dog {

    //最后一个 参数 calculte 为一个表达式,传入两个 Int 并返回 Int
    fun run(time: Int, distance: Int, calculate: (Int, Int) -> Int) {
        KtTools.p("dog run $distance 米 use $time 秒 speed = ${calculate(time, distance)}米/秒")
    }

    //最后一个 参数 barkTimes 为一个表达式,传入一个 Int 并返回 Unit 即可以不返回
    fun bark(dogName: String, barkVoice: (String) -> Unit) {
        barkVoice(dogName)
    }

    // 无参数 午饭回
    fun slowRun(slow: () -> String) {
        KtTools.p("${slow()}")

    }

    fun jump(bodyWeight: Int, height: Int, jumpAbility: (Int, Int) -> Int) {
        KtTools.p("这只 爆炸犬的 跳跃能力为 ${jumpAbility(height, bodyWeight)} 级")
    }

}

val calculateAbility: (Int, Int) -> Int = { x, y -> x / y }
//可以缩写,能缩写因为有 返回值类型推断,
//为了代码可读性,不建议使用 简写,如果表达式复杂,一眼看不出来类型,那不是还要推演一遍更麻烦
val ca = { x: Int, y: Int -> x / y }

以上是Kotlin中的Lambda表达式使用方式,对比Java 是简单方便了
当我开始撸的时候,我发现 kotlin 无法直接 声明接口参数并使用 Lambda 表达式传入

但是在Java 中声明,却可以在kotlin 中无缝调用
比如 Thread类 和 Runable接口

问题:在java 声明的接口参数方法,在kotlin 可以使用 Lambda表达式,而在Kotlin 中声明 同样的方法 却不可以 以表达式的方式调用,只能再写一个函数,并返回 接口实现类

问题示例代码:

JAVA

    public class MyThread {
    public MyThread(MyRunable target) {
        target.run();
        KtTools.p("在 MyThread 类的 构造中执行 类 run");
    }
    public void start(MyRunable runable){
        runable.run();
        KtTools.p("在 MyThread 类的 start 方法中 执行类 run");
    }
}

Kotlin


package main.class_7

import main.tools.KtTools

class MyThreadToKt( target: MyRunable?=null) {
    init {
        KtTools.p("在 MyThread 类的 构造中执行 类 run")
    }
    fun start(runable: MyRunable) {
        runable.run()
        KtTools.p("在 MyThread 类的 start 方法中 执行类 run")
    }
}

最后再kotlin 中调用

  //调用 java 中的 类‘
 val myThread = MyThread {  KtTools.p("在 MyThread 对象创建时  执行") }
    myThread.start{
        KtTools.p("在 MyThread 对象调用 start 时 执行")
    }

//调用kotlin 中的类
 val threadKt = MyThreadToKt{ }

        threadKt.start(object :MyRunable{
            override fun run() {

            }

很有趣的,这里创建 MyThreadToKt 时,编译器会提示找不到构造器
因为缺少 constructor(target: () -> Unit) : this(null) 接受无返回的表达式 构造类型

1.也就述说,他不支持在默认构造中添加传入一个匿名对象

2.在方法中 也不能直接传入 匿名表达式,只能传入匿名类或者 返回值为 声明的接口类型 的对象

这不是很蛋疼吗?我在java 写就可以,在kotlin 中就不可以

  • -! 不知道 是不是我知识点没摸透,或是其他未知因素

如果你也有同样的思考,或者解决方法,其他理解思路
希望你在下方评论区留言,感激不尽。

END

    原文作者:_RANGO
    原文地址: https://www.jianshu.com/p/443bdc31fe07
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞