2016-06-03 15 views
50

Tôi tự hỏi nếu có một cách để kiểm tra xem một biến số lateinit đã được khởi tạo chưa.Cách kiểm tra xem biến "lateinit" đã được khởi tạo chưa?

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

Có lẽ những gì bạn cần là làm cho nullable tài sản (thay đổi loại để file ''?) Và chỉ cần kiểm tra nếu nó là null thay vì ? –

+0

Vâng, tôi thực sự đã thử điều đó và nó sẽ thực hiện thủ thuật, tuy nhiên tôi sẽ phải chỉnh sửa 'allSeries' var thành' seriesDir? .listFiles() ?. map {it.name} ?. toTypedArray() ', đó là không phải là rất "đẹp" –

+1

Bạn có thể làm một kiểm tra null đồng bằng cũ và đúc thông minh sẽ làm cho nó đẹp hơn. 'if (seriesDir! = Null) {' 'allSeries = seriesDir.listFiles(). Map {it.name} .toTypedArray()' '}' –

Trả lời

12

Hãy thử sử dụng và bạn sẽ nhận được UninitializedPropertyAccessException nếu không được khởi tạo.

lateinit dành riêng cho trường hợp các trường được khởi tạo sau khi xây dựng, nhưng trước khi sử dụng thực tế (một mô hình mà hầu hết các khuôn khổ tiêm sử dụng). Nếu đây không phải là số điện thoại của bạn, lateinit có thể không phải là lựa chọn đúng đắn.

EDIT: Dựa trên những gì bạn muốn làm một cái gì đó như thế này sẽ làm việc tốt hơn:

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

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

Tôi có một ứng dụng JavaFX, và tôi có một nút sẽ luôn luôn vô hiệu hóa trừ khi một biến (đó là 'lateinit') đã được khởi tạo. Nói cách khác: Tôi muốn nút bị vô hiệu hóa miễn là biến chưa được khởi tạo. Có cách nào tốt để làm điều đó không? –

+0

@MathewHany Làm thế nào nó sẽ được khởi tạo bình thường? Bạn có thể muốn xem xét thuộc tính getter/setters và SimpleBooleanProperty mà bạn có thể liên kết với thuộc tính disabled của nút – Kiskae

+1

Để cụ thể hơn, tôi có một ứng dụng đơn giản chứa 4 nút, nút đầu tiên sẽ mở hộp thoại DirectoryChooser và 3 khác sẽ bị tắt, khi người dùng chọn thư mục thì tất cả các nút khác sẽ khả dụng cho người dùng. –

91

Có là một cải tiến lateinit trong Kotlin 1.2 cho phép để kiểm tra trạng thái khởi tạo của lateinit biến trực tiếp:

lateinit var file: File  

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

Xem thông báo trên JetBrains blog hoặc KEEP proposal.

CẬP NHẬT: Kotlin 1.2 đã được phát hành. Bạn có thể tìm lateinit cải tiến ở đây:

+2

@ fer.marino: Vâng, Kotlin 1.2 thực sự cho phép bạn sử dụng 'lateinit' cũng cho các biến cục bộ, xem http://kotlinlang.org/docs/reference/whatsnew12.html#lateinit-top-level-properties-and- local-variables – xsveda

+6

Bây giờ Kotlin 1.2 được phát hành, đây sẽ là câu trả lời được chấp nhận – kike

Các vấn đề liên quan