2016-03-27 6 views
6

wir sicher sein das nächste Stück von Kotlin Code vorstellen, dass einige Abfrage in einer Datenbank ausführt, durch einen JDBC-Verbindungsmittel:Kotlin: „synchronisiert“ macht Compiler nicht um die Initialisierung einer Variablen

var results : ResultSet 
    preparedStatement.clearParameters() 
    preparedStatement.setInt(1,value1); 
    preparedStatement.setInt(2,value2) 
    results = preparedStatement.executeQuery() 
    while(results.next()) { 
     // parse results 
    } 

, die kompiliert ohne Probleme. Allerdings, wenn ich versuche, Thread-Sicherheit auf den Zugang zum preparedStatement hinzuzufügen:

var results : ResultSet 
    synchronized(preparedStatement) { 
     preparedStatement.clearParameters() 
     preparedStatement.setInt(1,value1); 
     preparedStatement.setInt(2,value2) 
     results = preparedStatement.executeQuery() 
    } 
    while(results.next()) { 
     // parse results 
    } 

... Ich bekam ein „Variable‚Ergebnisse‘initialisiert werden muss“. Es scheint, dass der synchronized Block als ein bedingter Block fungiert, aber Sie können sicher sein, dass er einmal vor dem while Block ausgeführt wird.

Ich habe diesen gleichen Block in Java implementiert und ich bekomme den Fehler nicht. Ist das ein Design-/Implementierungsfehler von Kotlin? Oder hat es einen guten Grund, sich so zu verhalten?

Antwort

15

synchronized ist nur eine Inline-Funktion und der Compiler weiß nicht, ob Lambda einmal ausgeführt oder überhaupt ausgeführt wird. Idiomatische Art und Weise ist es, Wert von Lambda zurückzugeben und es dem lokalen zuzuteilen:

val results = 
    synchronized(preparedStatement) { 
    preparedStatement.clearParameters() 
    preparedStatement.setInt(1,value1); 
    preparedStatement.setInt(2,value2) 
    preparedStatement.executeQuery() 
    } 
+0

groß! vielen Dank – Mario

+0

@Ilya gibt es irgendwelche Pläne, den Compiler zur Unterstützung solcher Fälle zu machen? Mit 'mustExecute' Schließer oder etwas? – voddan

Verwandte Themen