gpt4 book ai didi

kotlin - 如何从 `return` 调用内部调用 `use` ?

转载 作者:行者123 更新时间:2023-12-02 07:14:39 25 4
gpt4 key购买 nike

在 Kotlin 中,此代码可以编译:

private fun bar(): Boolean = TODO()

fun works(): Int {
while (true) {
if (bar()) {
return 5
}
}
}

(这是我的真实代码的简化示例,用于说明我遇到的问题。)

我实际上需要在此循环期间使用一个文件,并在退出时关闭:

fun openFile(): InputStream = TODO()

fun doesnt_work(): Int {
openFile().use { input ->
while (true) {
if (bar()) {
return 5
}
}
}
} // line 42

这不能编译。我收到错误:

Error:(42, 5) Kotlin: A 'return' expression required in a function with a block body ('{...}')

我找到了两种方法来解决这个问题,但都有点尴尬。

一种方法是使用变量来保存结果,并在设置后立即退出循环:

fun works_but_awkward(): Int {
openFile().use { input ->
val result: Int
while (true) {
if (bar()) {
result = 5
break
}
}
return result
}
}

这在我的实际代码中尤其尴尬,因为我有一个嵌套循环,所以我需要使用带标签的中断。

解决此问题的另一种方法是为循环提供一个命名函数:

fun workaround_with_named_function(): Int {
fun loop(input: InputStream): Int {
while (true) {
if (bar()) {
return 5
}
}
}
return openFile().use { loop(it) }
}

这看起来好一点,但我仍然感到惊讶的是 use 抽象是如此泄漏,以至于我无法从循环内提前返回。有没有一种方法可以在循环中使用 use 并提前返回,这样就不那么尴尬了?

最佳答案

因为 Kotlin 编译器不够智能,无法理解使用内部代码的 use 会从函数中返回一些内容。这种行为的原因是无法保证编译器 lambda 只会被调用一次。

解决此问题的另一种方法是在函数末尾抛出异常:

fun doesnt_work(): Int {
openFile().use { input ->
while (true) {
if (bar()) {
return 5
}
}
}
throw IllegalStateException("Something goes wrong")
}

P.S. 我不确定,但似乎可以在 contract system 时无需任何修改地编译它。将被添加到 Kotlin 中。它可能会出现在 1.3 版本中

关于kotlin - 如何从 `return` 调用内部调用 `use` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49743404/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com