2016-06-03 2 views
50

Интересно, есть ли способ проверить, была ли инициализирована переменная lateinit.Как проверить, была ли инициализирована переменная «lateinit»?

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

Может быть, что вам нужно сделать свойство Nullable (тип изменения в файл ''?) И просто проверить, если она равна нулю вместо ? –

+0

Ну, я на самом деле пробовал это, и он будет делать трюк, однако мне придется отредактировать var 'allSeries' для' seriesDir? .listFiles() ?. map {it.name} ?. toTypedArray() ', что не очень «красиво» –

+1

Вы можете сделать обычную старую нулевую проверку, а умный листинг сделает ее красивее. 'if (seriesDir! = Null) {' 'allSeries = seriesDir.listFiles(). Map {it.name} .toTypedArray()' '}' –

ответ

12

Попробуйте использовать его, и вы получите UninitializedPropertyAccessException, если он не инициализирован.

lateinit предназначено специально для случаев, когда поля начинаются после строительства, но до фактического использования (модель, используемая большинством схем инъекций). Если это не ваш usecase lateinit, возможно, не правильный выбор.

EDIT: Исходя из того, что вы хотите сделать что-то подобное будет работать лучше:

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

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

У меня есть приложение JavaFX, и у меня есть кнопка, которая будет всегда отключается, если переменная (которая является «lateinit') была инициализирована. Другими словами: я хочу, чтобы кнопка была отключена, пока переменная не была инициализирована. Есть ли хороший способ сделать это? –

+0

@MathewHany Как это будет нормально инициализироваться? Возможно, вам захочется посмотреть на свойства getter/seters и SimpleBooleanProperty, которые вы можете привязать к отключенному свойству кнопки – Kiskae

+1

Чтобы быть более конкретным, у меня есть простое приложение, содержащее 4 кнопки, первая кнопка откроет диалоговое окно DirectoryChooser и другие 3 будут отключены, когда пользователь выберет каталог, тогда все остальные кнопки будут доступны пользователю. –

91

Существует lateinit улучшение Котлин 1.2, что позволяет проверять состояние инициализации lateinit переменной непосредственно:

lateinit var file: File  

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

См. Аннуляцию на JetBrains blog или KEEP proposal.

UPDATE: Kotlin 1.2 был выпущен. Вы можете найти lateinit улучшений здесь:

+2

@ fer.marino: Ну, Kotlin 1.2 фактически позволяет использовать 'lateinit' также для локальных переменных, см. Http://kotlinlang.org/docs/reference/whatsnew12.html#lateinit-top-level-properties-and- локальные переменные – xsveda

+6

Теперь выпущен Kotlin 1.2, это должен быть принятый ответ – kike

Смежные вопросы