2016-06-03 14 views
50

Ich frage mich, ob es eine Möglichkeit gibt zu überprüfen, ob eine lateinit Variable initialisiert wurde.Wie überprüft man, ob eine "lateinit" -Variable initialisiert wurde?

import javafx.application.Application 
import javafx.event.EventHandler 
import javafx.geometry.Insets 
import javafx.geometry.Pos 
import javafx.scene.Scene 
import javafx.scene.control.Button 
import javafx.scene.control.ComboBox 
import javafx.scene.layout.VBox 
import javafx.stage.DirectoryChooser 
import javafx.stage.Stage 
import java.io.File 

class SeriesManager() { 
    lateinit var seriesDir: File 
    val allSeries by lazy { 
     seriesDir.listFiles().map { it.name }.toTypedArray() 
    } 
} 

class SeriesManagerUI : Application() { 
    override fun start(primaryStage: Stage) { 
     val sm = SeriesManager() 

     val setSeriesDirBtn = Button("Change all series location").apply { 
      onAction = EventHandler { 
       sm.seriesDir = DirectoryChooser().apply { 
        title = "Choose all series location" 
       }.showDialog(primaryStage) 
      } 
     } 
     val allSeriesList = ComboBox<String>().apply { 
      promptText = "Select a series from here" 
      isDisable = // I want this to be always true, unless the SeriesManager.seriesDir has been initialized 
     } 
     val setCurrentEpisodeBtn = Button("Change the current episode") 
     val openNextEpisode = Button("Watch the next episode") 

     val layout = VBox(
      setSeriesDirBtn, 
      allSeriesList, 
      setCurrentEpisodeBtn, 
      openNextEpisode 
     ).apply { 
      padding = Insets(15.0) 
      spacing = 10.0 
      alignment = Pos.CENTER 
     } 

     primaryStage.apply { 
      scene = Scene(layout).apply { 
       minWidth = 300.0 
       isResizable = false 
      } 

      title = "Series Manager" 
     }.show() 
    } 
} 

fun main(args: Array<String>) { 
    Application.launch(SeriesManagerUI::class.java, *args) 
} 
+1

Vielleicht, was Sie brauchen, ist die Eigenschaft auf NULL festlegbare (ändern Typ 'Datei'?) Zu machen und einfach überprüfen, ob es null statt ? –

+0

Nun, ich habe es tatsächlich ausprobiert und es wird den Trick machen, aber ich werde die 'allSeries' var zu' seriesDir? .listFiles() ?. map {it.name} ?. toTypedArray() 'bearbeiten müssen nicht sehr "hübsch" –

+1

Sie können einen einfachen alten Null-Check machen und Smartcast wird es hübscher machen. 'if (serialDir! = Null) {' 'allSeries = seriesDir.listFiles(). Map {it.name} .toTypedArray()' '}' –

Antwort

12

versuchen, es zu verwenden, und Sie werden eine UninitializedPropertyAccessException erhalten, wenn es nicht initialisiert wird.

lateinit ist speziell für Fälle, in denen Felder nach der Konstruktion initialisiert werden, aber vor der eigentlichen Verwendung (ein Modell, das die meisten Injektion Frameworks verwenden). Wenn dies nicht Ihr Anwendungsfall lateinit ist möglicherweise nicht die richtige Wahl.

EDIT: Nach dem, was Sie etwas tun wollen, wie dies besser funktionieren würde:

val chosenFile = SimpleObjectProperty<File?> 
val button: Button 

// Disables the button if chosenFile.get() is null 
button.disableProperty.bind(chosenFile.isNull()) 
+0

Ich habe eine JavaFX-Anwendung, und ich habe eine Schaltfläche, die wird beable ist immer deaktiviert, es sei denn, eine Variable (die 'laterinit' ist) wurde initialisiert. Mit anderen Worten: Ich möchte, dass die Schaltfläche deaktiviert wird, solange die Variable nicht initialisiert wurde. Gibt es einen guten Weg, das zu tun? –

+0

@MathewHany Wie würde es normal initialisiert werden? Vielleicht möchten Sie Eigenschaften Getter/Setter und eine SimpleBooleanProperty, die Sie an die deaktivierte Eigenschaft der Schaltfläche binden können – Kiskae

+1

Um genauer zu sein, habe ich eine einfache App, die 4 Tasten enthält, öffnet die erste Schaltfläche ein DirectoryChooser-Dialog und die anderen 3 werden deaktiviert, wenn der Benutzer ein Verzeichnis auswählt, dann sind alle anderen Tasten für den Benutzer verfügbar. –

91

Es gibt eine lateinit Verbesserung in Kotlin 1.2, die den Initialisierungszustand von lateinit Variable prüfen können direkt:

lateinit var file: File  

if (::file.isInitialized) { ... } 

Siehe die Ankündigung auf JetBrains blog oder die KEEP proposal.

UPDATE: Kotlin 1.2 wurde veröffentlicht. Sie können lateinit Erweiterungen finden Sie hier:

+2

@ fer.marino: Nun, Kotlin 1.2 erlaubt Ihnen tatsächlich, 'laterinit' auch für lokale Variablen zu verwenden, siehe http://kotlinlang.org/docs/reference/whatsnew12.html#lateineit-top-level-properties-and- local-variables – xsveda

+6

Nun ist Kotlin 1.2 freigegeben, dies sollte die akzeptierte Antwort sein – kike

Verwandte Themen