确保在Kotlin中初始化val
我在Java中有以下方法:确保在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();
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()
是否内联,编译器可以尝试进一步解决问题,但很快就会变得复杂。