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

Converting Thread/Runnable implementation from Java to Kotlin

我有一个现有的Java类ThreadUtils,其方法为every,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

而失败

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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退出,以帮助自己分离事物,但这也以相同的方式失败:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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或类似样式的闭包/ lambda,该闭包/ lambda不会尝试从其定义函数中return


在Kotlin中,lambda内的return语句的工作方式与Java中的不同。如果仅编写return,则意味着从用关键字fun声明的最里面的函数返回,而忽略了lambdas-在您的代码中,这意味着"从every返回"。

要从lambda返回,请使用合格的return@label-在您的情况下,它是return@Thread(第二个示例为return@Runnable),如以下简化代码段所示:

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

(此代码的可运行演示)

此外,您可能会发现kotlin-stdlib中有一个thread { ... }函数很有用(并且类似地,其lambda的return语句是return@Thread)。

您可以在语言参考和此答案中找到更详细的解释。