8

我有一个现有的 Java 类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或类似样式的闭包/ lambda,它不尝试return 定义它的函数中获取?

4

1 回答 1

11

在 Kotlin 中,returnlambda 中的语句的工作方式与 Java 中的不同。如果你写 just return,它意味着从用关键字声明的最里面的函数返回fun,并且它忽略 lambdas - 在你的代码中,它意味着'从every'返回。

要从 lambda 返回,请使用合格return@label的——在您的情况下,它是return@Threadreturn@Runnable对于第二个示例),就像在这个简化的代码段中一样:

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

(此代码的可运行演示)

此外,还有一个您可能会觉得有用的thread { ... }函数(类似地,它的 lambda 的 return 语句是)。kotlin-stdlibreturn@thread

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

于 2017-04-12T11:02:49.370 回答