To dobrze przedstawia, jak testować, jeśli Zainicjowano LATINIT VAR. Jednak w przykładzie Lateinit Var jest dogodnie zlokalizowany w tej samej klasie.

Jak robisz to samo z poza klasę? To jest sytuacja, którą mam:

foo.kt

class Foo {
    lateinit var foo: String
}

bar.kt

class Bar {
    fun doSomething() {
        val foo = Foo().foo
        if (::foo.isInitialized) { // Unsupported [reference to variables aren't supported yet]
            Log.i("TAG", "do something")
        }
    }
}

Co jest dla tego obejście?

2
El Sushiboi 20 marzec 2020, 21:47

2 odpowiedzi

Najlepsza odpowiedź

Gdyby to zadziałało, musisz to zrobić

val foo = Foo()
if (foo::foo.isInitialized)
    //... 

Sposób, w jaki to robisz, próbujesz uzyskać odniesienie do lokalnej zmiennej, która nie jest nieruchomością. Dlatego błąd mówi, że "Odniesienie do zmiennych nie jest jeszcze obsługiwane", a nie "podkładem, nie jest dostępne w tym momencie". Dostęp do uzyskania dostępu do Gettera nieruchomości {x0}} przy przypisaniu zmiennej lokalnej, więc nie powiedzie się jeszcze, gdyby nie został jeszcze zainicjowany.

Ale to nie działa z powodu ograniczeń kompilatorowych. Możesz po prostu dodać Getter

val fooReady: Boolean get() = ::foo.isInitialized 

Powiedziałbym jednak, że projekt ma bardzo słabe kapsułkowanie, jeśli zajęcia zewnętrzne muszą sprawdzić, czy dana nieruchomość publiczna jest jeszcze inicjowana. Moim zdaniem każde użycie isInitialized jest zapach kodu. Jeśli chcesz chronić połączenia do Gettera z isInitialized, może być równie dobrze uczynić nieruchomością. Następnie możesz użyć znanych idiomów kontroli zerowej zamiast uciekania się do refleksji, a będzie działać w znanym sposobie nawet do zajęć zewnętrznych, które go udostępniają.

2
Tenfour04 20 marzec 2020, 20:59

Jeśli obiekt innej klasy musi podjąć decyzję na podstawie tego, czy nieruchomość jest inicjowana, a następnie posiadanie tej właściwości inicjowanej - lub odpowiadając, czy został już zainicjowany - jest publiczną zdolnością biznesową twojego obiektu i dlatego polecam Aby po prostu sprawić, że jest częścią twojego publicznego interfejsu API przez {X0}}, która wykorzystuje fakt, że sam obiekt może sprawdzić stan jego właściwości {X1}}.

0
ryfterek 20 marzec 2020, 19:43