Если вы на самом деле не заботитесь о том, какого типа будет эта вещь, вы можете параметризовать ее с помощью [_, _]. Примерами могут быть такие вещи, как
val thing = new SomeClass[_, _]()
или
def thingDoer(sc: SomeClass[_, _]) { /* Stuff */ }
Чтобы быть более понятным в своей природе, подчеркивание известно как «экзистенциальный тип», и оно в основном эквивалентно необработанному типу в Java, и оно также может функционировать подобно типу подстановочных знаков из Java. Например, этот шизофренический код Java
public void thingThatTakesAMapList(List<? extends Map> mapList) { /* Whatever */ }
совпадает с кодом Scala
def thingThatTakesAMapList(mapList: List[_ <: Map[_, _]]) { /* Some incredibly wild subroutine */ }
Кроме того, стоит отметить, что различие между List [Any] и List [_] является ... очень тонким. Это значит, что первый - это список Any, а второй - это список [Я не знаю / мне все равно]. _ сильно отличается от Any, хотя. Например, если у вас был класс с этой подписью
class SillyClass[T <: Map[_, _]]
было бы недопустимо делать это
val thing = new SillyClass[Any]()
в то время как может быть действительным для вас, чтобы сделать это
val thing = new SillyClass[HashMap[_, _]]()
и, если функция принимает SillyClass в качестве параметра, вы можете написать
def sillyClassTaker(sc: SillyClass[_])
и будьте уверены, что sc не будет параметризован над типом Any; он параметризован по какому-то неизвестному подклассу Map [_, _]. Иными словами, подчеркивание является заполнителем , но для него все еще требуется наличие допустимых параметров типа. Так что, хотя это все круто и все ... Я не особо рекомендую использовать это слишком много. Если вам нужно что-то сделать ... подстановочный знак-y или просто не заботиться о параметрах типа, это хороший вариант для рассмотрения.