Різниця між "*" та "Будь-яким" у дженериках Котліна


106

Я не впевнений, що повністю розумію різницю між SomeGeneric<*>і SomeGeneric<Any>. Я думаю, що *представляє все, що завгодно (wildcard) і Anyпредставляє об'єкт, який ВСІ успадковують об'єкти Тож здається, вони повинні бути однаковими, але чи не так?

Відповіді:


158

Можливо, буде корисно подумати про проекцію зірки як про спосіб представити не просто будь-який тип, а якийсь фіксований тип, який ви не знаєте, що саме.

Наприклад, тип MutableList<*>представляє список чогось (ви не знаєте, що саме). Тож якщо ви спробуєте щось додати до цього списку, вам це не вдасться. Це може бути список Strings, або список Ints, або список чогось іншого. Компілятор забороняє взагалі містити будь-який об’єкт у цьому списку, оскільки він не може перевірити, що список приймає об'єкти такого типу. Однак, якщо ви спробуєте витягти елемент із такого списку, ви неодмінно отримаєте об'єкт типу Any?, оскільки всі об'єкти в Котліні успадковують відAny .

З коментаря asco нижче:

Крім того, вони List<*>можуть містити об'єкти будь-якого типу, але тільки цього типу, тому вони можуть містити рядки (але тільки рядки), тоді як вони List<Any> можуть містити рядки та цілі числа та що інше, все в тому ж списку.


83
Приємна відповідь, для деяких може бути корисним додати, що Список <*> може містити об'єкти будь-якого типу, але лише цього типу, тому він може містити рядки (але лише рядки), тоді як Список <Any> може містити рядки та цілі числа та що ні, все в одному списку.
fweigl

1
Ось цікава стаття зі схожим поясненням: typealias.com/guides/star-projections-and-how-they-work
croc

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.