Bir "lateinit" değişkeninin başlatılıp başlatılmadığı nasıl kontrol edilir?


428

Bir lateinitdeğişkenin başlatılıp başlatılmadığını kontrol etmenin bir yolu olup olmadığını merak ediyorum . Örneğin:

class Foo() {

    private lateinit var myFile: File

    fun bar(path: String?) {
        path?.let { myFile = File(it) }
    }

    fun bar2() {
        myFile.whateverMethod()
        // May crash since I don't know whether myFile has been initialized
    }
}

3
Belki ihtiyacınız olan şey özelliği nulllable (tür değiştir File?) yapmak ve bunun yerine null olup olmadığını kontrol etmektir?
Marcin Koziński

1
Aslında, bunu denedim ve hile yapacağım, ancak çok "güzel" olmayan allSeriesvar düzenlemek zorunda kalacakseriesDir?.listFiles()?.map { it.name }?.toTypedArray()
Mathew Hany

1
Sade eski bir null kontrol yapabilirsiniz ve akıllı oyuncu daha güzel hale getirecektir. if (seriesDir != null) { allSeries = seriesDir.listFiles().map { it.name }.toTypedArray() }
Marcin Koziński

Lütfen daha güncel bir cevap
misanthrope

Yanıtlar:


977

lateinitKotlin 1.2'de lateinitdeğişkenin başlatma durumunu doğrudan kontrol etmeyi sağlayan bir gelişme var :

lateinit var file: File    

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

JetBrains blogundaki duyuruyu veya KEEP teklifini görün .

GÜNCELLEME: Kotlin 1.2 yayınlandı. lateinitGeliştirmeleri burada bulabilirsiniz :


3
@ fer.marino: Kotlin 1.2 aslında lateinityerel değişkenler için de kullanmanıza izin veriyor , bkz. kotlinlang.org/docs/reference/…
xsveda

9
this :: lateinitVar.isInitialized
vihkat

17
daha ::önce ne anlama geliyor file?
Malwinder Singh

5
@MalwinderSingh bir üye başvurusu veya bir sınıf başvurusu oluşturur.
notGeek

5
Kotlin'e aşık oldum
Naveed Ahmad

46

Bir .isInitializedözelliği kullanarak lateinit değişkeninin başlatma durumunu kontrol edebilirsiniz.

if(::file.isInitialized){
    //File is initialized
}else{
    //File is not initialized
}

Bu soruya bir cevap sağlamaz. Bir yazardan eleştiri veya açıklama istemek için gönderilerinin altına bir yorum bırakın. - Yorumdan
gforce301

2
@ gforce301 Kesinlikle kontrol için kullanılacaktır.
Nikhil Katekhaye

39

Kullanmayı deneyin ve UninitializedPropertyAccessExceptionbaşlatılmazsa bir alacaksınız .

lateinitözellikle alanların inşaattan sonra, ancak gerçek kullanımdan önce başlatıldığı durumlar içindir (çoğu enjeksiyon çerçevesinin kullandığı bir model). Bu değilse, kullanım durumunuz lateinitdoğru seçim olmayabilir.

EDIT: Böyle bir şey yapmak istediğinize dayanarak daha iyi çalışır:

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

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

Bir JavaFX uygulaması var ve bir değişken (ki lateinit) başlatılmadıkça her zaman devre dışı bırakılacak bir düğme var . Başka bir deyişle: Değişken başlatılmadığı sürece düğmenin devre dışı bırakılmasını istiyorum. Bunu yapmanın iyi bir yolu var mı?
Mathew Hany

@MathewHany Normal şekilde nasıl başlatılır? Düğmenin devre dışı özelliğine bağlayabileceğiniz özellik alıcı / ayarlayıcılarına ve SimpleBooleanProperty'ye bakmak isteyebilirsiniz
Kiskae

1
Daha spesifik olmak gerekirse, 4 düğme içeren basit bir uygulamam var, ilk düğme bir DirectoryChooser iletişim kutusu açacak ve diğer 3 devre dışı bırakılacak, kullanıcı bir dizin seçtiğinde diğer tüm düğmeler kullanıcı tarafından kullanılabilecek.
Mathew Hany

Birçok dosyayı seçilen dosyayı tutmak için bir SimpleObjectProperty kullanarak, ardından isNulldiğer düğmeleri devre dışı bırakmak için bağlayıcıyı kullanarak yerel olarak uygulayabilirsiniz .
Kiskae

1
kotlinlang.org/docs/reference/… xsveda cevabı daha güncel
Serge

19

Bunu şu şekilde kolayca yapabilirsiniz:

::variableName.isInitialized

veya

this::variableName.isInitialized

Ancak bir dinleyicinin veya sınıfın içindeyseniz, bunu yapın:

this@YourClassName::variableName.isInitialized

Not: Yukarıdaki ifadeler, değişkenin bildirildiği aynı dosyaya (aynı sınıf veya iç sınıf) yazıyorsanız, ancak diğer sınıfın değişkenini (üst sınıfta değil veya başka bir dosya) , örneğin:

class Test {
    lateinit var str:String
}

Ve str'nin başlatılıp başlatılmadığını kontrol etmek için:

resim açıklamasını buraya girin

Biz alanını erişen burada ne işin var striçinde Testsınıf Test2sınıfının. Ve var bir hata destek alan var bu noktada erişilebilir değildir. Bu konuda zaten sorulan bir soruyu kontrol edin .


12

Kabul edilen cevap bana bir derleyici hatası veriyor Kotlin 1.3+, daha thisönce anahtar kelimeden açıkça bahsetmek zorunda kaldım ::. Aşağıda çalışma kodu.

lateinit var file: File

if (this::file.isInitialized) {

    // file is not null
}

Çözülmemiş başvuru gibi bir hata veren bu denetimi kullandığımda yerel bir init değişkeni kullanıyorum
MarGin

3

lateinit varA'nın başlatılıp başlatılmadığını veya .isInitializedo özelliğe başvuruda a kullanılıp kullanılmadığını kontrol etmek için:

if (foo::bar.isInitialized) {
    println(foo.bar)
}

Bu kontrol yalnızca sözcüksel olarak erişilebilen, yani aynı türde veya dış türlerden birinde veya aynı dosyada en üst düzeyde bildirilen özellikler için kullanılabilir.


1
daha ::önce ne anlama geliyor bar?
Malwinder Singh

@Malwinder Singh "bir üye referansı veya sınıf referansı oluşturur" - Kotlin Doc
DMonkey

0
kotlin.UninitializedPropertyAccessException: lateinit property clientKeypair has not been initialized

Bytecode diyor ki ... filan filan ..

public final static synthetic access$getClientKeypair$p(Lcom/takharsh/ecdh/MainActivity;)Ljava/security/KeyPair;

`L0
LINENUMBER 11 L0
ALOAD 0
GETFIELD com/takharsh/ecdh/MainActivity.clientKeypair : Ljava/security/KeyPair;
DUP
IFNONNULL L1
LDC "clientKeypair"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.throwUninitializedPropertyAccessException (Ljava/lang/String;)V
    L1
ARETURN

L2 LOCALVARIABLE $ bu Lcom / takharsh / ecdh / MainActivity; L0 L2 0 MAXSTACK = 2 MAXLOCALS = 1

Kotlin, aynı örneğin ekstra bir yerel değişkeni oluşturur ve null olup olmadığını kontrol eder, null sonra 'throwUninitializedPropertyAccessException' atarsa ​​yerel nesneyi döndürür. Yukarıdaki bayt kodu burada açıklanmıştır Çözüm Kotlin 1.2'den beri hava lateinit var başlatılmış veya kullanılmamış olup olmadığını kontrol etmenizi sağlar.isInitialized

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.