将 Thread/Runnable 实现从 Java 转换为 Kotlin

Converting Thread/Runnable implementation from Java to Kotlin

我有一个现有的 Java class ThreadUtils,其方法 every 看起来像:

public class ThreadUtil {

    public static Thread every(int seconds, Runnable r) {
        Thread t = new Thread(() -> {
            while(true) {
                r.run();
                try {
                    Thread.sleep(1000 * seconds);
                } catch (InterruptedException e) {
                    return;
                }
            }
        });
        t.start();
        return t;
    }
}

我正在尝试将其转换为 Kotlin。我对 Runnable 闭包有点着迷。这失败了 return:

fun every(seconds: Int, r: Runnable): Thread {
    val t = Thread({
        while (true) {
            r.run()
            try {
                Thread.sleep((1000 * seconds).toLong())
            } catch (e: InterruptedException) {
                return // ERROR: This function must return a value of type Thread
            }
        }
    })
    t.start()
    return t
}

我也尝试拉出 Runnable 来帮助自己分离东西,但这也以同样的方式失败:

fun every(seconds: Int, r: Runnable): Thread {
    val internalRunnable = Runnable {
        while (true) {
            r.run()
            try {
                Thread.sleep((1000 * seconds).toLong())
            } catch (e: InterruptedException) {
                return // ERROR: This function must return a value of type Thread
            }
        }
    }
    val t = Thread(internalRunnable)
    t.start()
    return t
}

我如何实现一个 @FunctionalInterface 或类似的 closure/lambda 不尝试 return 从其中的函数 正在定义中?

在 Kotlin 中,lambda 中的 return 语句与 Java 中的语句工作方式不同。如果你只写 return,它意味着来自用关键字 fun 声明的最内层函数的 return,它会忽略 lambdas——在你的代码中,它意味着 'return from every'.

从 lambda 到 return,使用限定的 return@label-- 在你的例子中,它是 return@Thread(第二个例子是 return@Runnable),像这样简化片段:

for (i in 1..4) {
    Thread { 
        if (i % 2 == 0)
            return@Thread
        println("Thread $i")
    }.run()
}

(runnable demo of this code)

此外,kotlin-stdlib 中有一个 thread { ... } 函数,您可能会发现它很有用(同样,其 lambda 的 return 语句是 return@thread)。

您可以在 language reference and in .

中找到更详细的解释