Представьте себе следующий фрагмент кода Kotlin, который выполняет некоторый запрос к базе данных с помощью JDBC-коннектора:
var results : ResultSet preparedStatement.clearParameters() preparedStatement.setInt(1,value1); preparedStatement.setInt(2,value2) results = preparedStatement.executeQuery() while(results.next()) { // parse results }
который компилируется без проблем. Однако, когда я пытаюсь добавить безопасность потоков к доступу к readyStatement:
var results : ResultSet synchronized(preparedStatement) { preparedStatement.clearParameters() preparedStatement.setInt(1,value1); preparedStatement.setInt(2,value2) results = preparedStatement.executeQuery() } while(results.next()) { // parse results }
… Я получил «переменные» результаты, которые должны быть инициализированы » . Кажется, synchronized
блок действует как условный блок, но вы можете быть уверены, что он будет выполнен один раз, до блока while
.
Я реализовал этот же блок в Java, и я не получаю ошибку. Является ли это ошибкой дизайна / реализации Kotlin? Или у этого есть веская причина вести себя так?
synchronized
– это просто встроенная функция, и компилятор не знает, будет ли lambda выполняться один раз или даже выполнить вообще. Идиоматический способ – вернуть значение из лямбда и назначить его локальному:
val results = synchronized(preparedStatement) { preparedStatement.clearParameters() preparedStatement.setInt(1,value1); preparedStatement.setInt(2,value2) preparedStatement.executeQuery() }