次のようなメソッドThreadUtils
を持つ既存のJavaクラス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
}
定義されているreturn
関数からを試行しない@FunctionalInterface
または同様のスタイルのクロージャ/ラムダを実装するにはどうすればよいですか?
Kotlinでは、ラムダ内のreturn
ステートメントはJavaのステートメントとは動作が異なります。 return
だけを書くと、キーワードfun
で宣言された最も内側の関数から戻ることを意味し、ラムダを無視します。コードでは、「every
から戻る」を意味します。 。
ラムダから戻るには、修飾されたreturn@label
--を使用します。この場合、次の簡略化されたスニペットのように、return@Thread
(および2番目の例ではreturn@Runnable
)です。
for (i in 1..4) {
Thread {
if (i % 2 == 0)
return@Thread
println("Thread $i")
}.run()
}
また、thread { ... }
には kotlin-stdlib
関数があります(同様に、ラムダのreturnステートメントはreturn@thread
です)。