Różnica między „*” i „Any” w kotlinach generycznych

107

Nie jestem pewien, czy w pełni rozumiem różnicę między SomeGeneric<*>i SomeGeneric<Any>. Myślę, że *reprezentuje wszystko (symbol wieloznaczny) i Anyreprezentuje obiekt, z którego dziedziczą WSZYSTKIE obiekty. Wygląda więc na to, że powinny być takie same, ale czy tak jest?

Wheel Builder
źródło

Odpowiedzi:

159

Pomocne może być myślenie o projekcji gwiazdy jako o sposobie przedstawienia nie dowolnego typu, ale jakiegoś ustalonego typu, którego dokładnie nie wiesz.

Na przykład typ MutableList<*>reprezentuje listę czegoś (nie wiesz dokładnie, co). Więc jeśli spróbujesz dodać coś do tej listy, nie odniesiesz sukcesu. Może to być lista Strings, lista Ints lub lista czegoś innego. Kompilator w ogóle nie pozwoli na umieszczenie żadnego obiektu na tej liście, ponieważ nie może zweryfikować, czy lista akceptuje obiekty tego typu. Jeśli jednak spróbujesz wyciągnąć element z takiej listy, na pewno otrzymasz obiekt typu Any?, ponieważ wszystkie obiekty w Kotlinie dziedziczą po Any.

Z komentarza asco poniżej:

Dodatkowo List<*>może zawierać obiekty dowolnego typu, ale tylko tego typu, więc może zawierać ciągi (ale tylko ciągi znaków), podczas gdy List<Any> może zawierać ciągi, liczby całkowite i tak dalej, wszystkie na tej samej liście.

Alexander Udalov
źródło
83
Dobra odpowiedź, dla niektórych pomocne może być dodanie, że List <*> może zawierać obiekty dowolnego typu, ale tylko tego typu, więc może zawierać ciągi znaków (ale tylko ciągi znaków), podczas gdy lista <Any> może zawierać ciągi znaków i liczby całkowite oraz co nie, wszystko na tej samej liście.
fweigl
1
Tutaj ciekawy artykuł z podobnym wyjaśnieniem: typealias.com/guides/star-projections-and-how-they-work
croc