Значение по умолчанию - PullRequest
6 голосов
/ 28 декабря 2011

Скажем, у меня есть класс:

class SomeClass[+A <: AnyRef, +B <: Any]

Чтобы указать его, я всегда должен также указывать типы общих параметров.Т.е. чтобы указать его наиболее общую версию в качестве типа параметра метода, мне нужно сделать def someMethod(param1: SomeClass[AnyRef, Any]) или new SomeClass[AnyRef, Any], чтобы создать его экземпляр.Это становится большой болью, когда речь идет о более сложных типах, которые имеют сложные обобщения.

Есть ли способ сделать подразумеваемую часть [AnyRef, Any], когда я не предоставляю обобщенную информацию?Например, def someMethod(param1: SomeClass)?

Есть ли способ, которым _ мог бы помочь мне решить эту проблему и как?

PS Я прошу прощения за то, что изначально не сформулировал вопрос так четко.

Ответы [ 4 ]

7 голосов
/ 29 декабря 2011

Как предлагается в моем комментарии, выполнение чего-то подобного может сэкономить некоторую печать и довольно просто:

type SomeClassAny = SomeClass[AnyRef, Any]
5 голосов
/ 29 декабря 2011

Если вы на самом деле не заботитесь о том, какого типа будет эта вещь, вы можете параметризовать ее с помощью [_, _]. Примерами могут быть такие вещи, как

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 или просто не заботиться о параметрах типа, это хороший вариант для рассмотрения.

3 голосов
/ 28 декабря 2011

Как насчет этого?

scala> :paste
// Entering paste mode (ctrl-D to finish)

class SomeClass[+A <: AnyRef]

object SomeClass {
  def apply() = new SomeClass[AnyRef]
}

// Exiting paste mode, now interpreting.

defined class SomeClass
defined module SomeClass

scala> SomeClass()
res47: SomeClass[AnyRef] = SomeClass@4f63b5

Редактировать:

Я думаю, вы хотите что-то вроде аргументов по умолчанию, но на уровне типа.К сожалению, у Scala такой функции нет.Вы можете использовать псевдонимы типа, как предложено @hyhnhjl.Это мне кажется лучшим выбором.

1 голос
/ 28 декабря 2011

Обычно это может быть выведено из типов параметров конструктора, но если конструктор не принимает никаких параметров, вы должны явно указать тип. Конечно, как указывал отсутствующий фактор, вы всегда можете написать метод для этого, чтобы сэкономить время при наборе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...