Podczas rzucania zmiennej po prawej stronie przypisania, zaskakuję, że zmienna nadal zachowuje się jako typ rzucony, a nie jako oryginalny zdefiniowany. Czy robię coś złego lub jest problemem kompilatora?

Kod:

val hippoList = listOf<Hippo>(Hippo())
val hippoMutableList : MutableList<Hippo> = hippoList as MutableList<Hippo>
hippoList.add(Hippo())

Ponieważ hipolista jest z typu typu jest niezmienny. Jak więc próba uruchomienia funkcji Dodaj na niezmiennym typie nie jest spowodowany błędem kompilacji?

1
Eitanos30 18 październik 2020, 15:16

1 odpowiedź

Najlepsza odpowiedź

Jeśli robisz ona, oznacza to, że znasz więcej niż kompilator o tym kontekście egzekucji i mówisz kompilatorem, że ten hipolista jest melbullistą, więc na każdym następnym użyciu kompilatora hipolistycznego już wie, że to musi być dezulabliciel i pozwala na użycie metody add, ponieważ wcześniej rzuciłeś go do dEwableList. W rzeczywistości otrzymasz błąd środowiska wykonawczego UnsupportedOperationException, co oznacza, że tak naprawdę nie wiedziałeś więcej o tym kontekście egzekucji i zrobiłeś coś złego. Więc zamiast używać odlewania na własny pozwolić kompilatorowi, aby wykonać pracę.

W twoim przypadku zamiast odlewania do melbullistki, przekształć hipolistę do maleku hippoList.toMutableList()

To samo dzieje się, gdy używasz !! z odróżnego typu, aby nie mieć typu null, gdy używasz go, gdy wiesz więcej niż kompilator o kontekście wykonania. Oto mały przykład

val someNullableType: String? = null
val thisStringIsNotNull = someNullableType!!

Używając !! Na Somenullabletype opowiadamy kompilatorowi, że Somenustabletype nie jest również null, więc możemy napisać (jak w przypadku sprawy, w której informujesz, że twoja lista jest również dezułaLista)

someNullableType.length

Ale otrzymamy wyjątek wcześniej (w miejscu, gdzie użyliśmy !! Ulepsz kompilator)

3
szymon_prz 18 październik 2020, 12:51