Псевдоним типа Scala, включая сопутствующий объект [новичок] - PullRequest
7 голосов
/ 13 октября 2010

Я хотел бы написать псевдоним типа для сокращения красивого и инкапсулированного кода Scala.Предположим, у меня есть какая-то коллекция, обладающая свойством быть списком карт, значением которых являются кортежи.Мой тип написал бы что-то вроде List[Map[Int, (String, String)]], или что-то более общее, как позволяет мое приложение.Я мог бы вообразить наличие супертипа, запрашивающего Seq[MapLike[Int, Any]] или что-то еще, плавающее в моей лодке, с конкретными конкретными подклассами.

Затем я бы хотел написать псевдоним для этого длинного типа.

class ConcreteClass {
  type DataType = List[Map[Int, (String, String)]]
  ...
}

Я бы тогда с радостью использовал ConcreteClass#DataType везде, где я мог бы взять и использовать его.

Теперь предположим, что я добавляю функцию

def foo(a : DataType) { ... }

И я хочу вызвать ее изснаружи с пустым списком.Я могу позвонить foo(List()), но когда я захочу изменить свой базовый тип на другой тип Seq, мне придется вернуться и изменить этот код.Кроме того, это не очень явно, этот пустой список предназначен как DataType.А у сопутствующего объекта нет связанных List методов, поэтому я не могу вызвать DataType() или DataType.empty.Это будет еще более раздражающим, когда мне понадобятся непустые списки, так как мне придется выписать значительную часть этого длинного типа.

Можно ли как-нибудь попросить Scala понять мой тип как такой жевещь, включая объект-компаньон с его методами-создателями, в интересах сокращения кода и его «черного ящика»?Или какая-то причина, почему я не должен делать это в первую очередь?

Ответы [ 2 ]

7 голосов
/ 13 октября 2010

Ответ на самом деле был довольно прост:

class ConcreteClass {
  type DataType = List[String]
}
object ConcreteClass {
  val DataType = List
}
val d = ConcreteClass.DataType.empty

Это позволяет моему коду вызывать ConcreteClass.DataType для создания списков со всеми методами в List и без особых усилий.

Большое спасибоОлегу для понимания.Его ответ также лучше всего подходит в том случае, если вы не хотите делегировать в List какой-либо вызов ConcreteClass.DataType, но точно контролировать то, что вы хотите разрешить вызывающим абонентам.

5 голосов
/ 13 октября 2010

А как насчет этого? class ConcreteClass { type DataType = List[String] } object DataType { def apply(): ConcreteClass#DataType = Nil } //... val a = DataType()

...