Kotlin:"synchronized" 使编译器不确定变量的初始化
Kotlin: "synchronized" makes compiler not to be sure about the initialization of a variable
让我们想象下一段 Kotlin 代码,它通过 JDBC 连接器对数据库执行一些查询:
var results : ResultSet
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
results = preparedStatement.executeQuery()
while(results.next()) {
// parse results
}
编译没有问题。但是,当我尝试将线程安全添加到对 preparedStatement 的访问时:
var results : ResultSet
synchronized(preparedStatement) {
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
results = preparedStatement.executeQuery()
}
while(results.next()) {
// parse results
}
...我得到了一个"Variable 'results' must be initialized"。看起来 synchronized
块充当条件块,但您可以确定它会在 while
块之前执行一次。
我在 Java 中实现了相同的块,但没有收到错误。这是 Kotlin 的 design/implementation 错误吗?或者它有充分的理由这样做吗?
synchronized
只是一个内联函数,编译器不知道 lambda 是否会执行一次,甚至根本不会执行。惯用的方法是 return 来自 lambda 的值并将其分配给本地:
val results =
synchronized(preparedStatement) {
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
preparedStatement.executeQuery()
}
让我们想象下一段 Kotlin 代码,它通过 JDBC 连接器对数据库执行一些查询:
var results : ResultSet
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
results = preparedStatement.executeQuery()
while(results.next()) {
// parse results
}
编译没有问题。但是,当我尝试将线程安全添加到对 preparedStatement 的访问时:
var results : ResultSet
synchronized(preparedStatement) {
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
results = preparedStatement.executeQuery()
}
while(results.next()) {
// parse results
}
...我得到了一个"Variable 'results' must be initialized"。看起来 synchronized
块充当条件块,但您可以确定它会在 while
块之前执行一次。
我在 Java 中实现了相同的块,但没有收到错误。这是 Kotlin 的 design/implementation 错误吗?或者它有充分的理由这样做吗?
synchronized
只是一个内联函数,编译器不知道 lambda 是否会执行一次,甚至根本不会执行。惯用的方法是 return 来自 lambda 的值并将其分配给本地:
val results =
synchronized(preparedStatement) {
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
preparedStatement.executeQuery()
}