确保在Kotlin中初始化val

确保在Kotlin中初始化val,kotlin,Kotlin,我在Java中有以下方法: public void doSomething() { final boolean promote = false; final String bob; if (promote) { try(StringWriter sw = new StringWriter()) { sw.write("this is a test"); bob = sw.toString();

我在Java中有以下方法:

public void doSomething() {
    final boolean promote = false;
    final String bob;

    if (promote) {
        try(StringWriter sw = new StringWriter()) {
            sw.write("this is a test");
            bob = sw.toString();
        } catch (IOException e) {
            e.printStackTrace();
            throw new IllegalStateException();
        }
    } else {
        bob = "anaconda";
    }

    System.out.println(bob);
}
当我将其转换为Kotlin时:

    val promote = false
    val bob: String

    if (promote) {
        try {
            StringWriter().use { sw ->
                sw.write("this is a test")
                bob = sw.toString()
            }
        } catch (e: IOException) {
            e.printStackTrace()
            throw IllegalStateException()
        }
    } else {
        bob = "anaconda"
    }

    println(bob)
但我在最后一行得到一个编译器错误:
变量'bob'必须初始化。

当Java编译器非常确定变量已经初始化或抛出异常时,我看不出Kotlin怎么会无法初始化
bob
变量

bob
更改为
var
并对其进行初始化的唯一选项是什么?

将方法的结果分配给变量,如下所示:

bob = StringWriter().use { sw ->
    sw.write("this is a test")
    sw.toString()
}

Java编译器能够确定变量将被初始化,因为变量是一种语言特性。另一方面,
use
方法是一个库特性,其行为取决于实际导入和使用的实现。换句话说,Kotlin编译器无法知道作为参数传递给
use
的函数是否会立即被调用。

好吧,因为use是内联的,编译器会知道如果调用传递的函数,这将立即发生。@Rocoty注意,
use
是内联的,这取决于提供函数的库(在本例中为stdlib)。想象一下这样的实现:
inline fun T.use(block:(T)->R):R?{if(otherFunc()){block(this)}}else{null}
。根据
otherFunc()
是否内联,编译器可以尝试进一步解决问题,但很快就会变得复杂。