2010-10-13 4 views
7

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

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

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

Я бы тогда спокойно использовать ConcreteClass#DataType везде, где я могу взять один, и использовать его.

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

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

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

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

ответ

7

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

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

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

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

+2

Если вы не намереваетесь подклассы «ConcreteClass» переопределить «DataType», вам может быть лучше помещать как псевдонимы 'type', так и' val' в объект-компаньон (вместо того, чтобы иметь один в классе). Вот как работают псевдонимы в пакете «scala». –

+0

Ты действительно прав. Я сделаю это с этого момента. Благодарю. – Jean

+1

За исключением того, что d является типом List [Nothing] – sourcedelica

5

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

 
class ConcreteClass { 
    type DataType = List[String] 
} 
object DataType { 
    def apply(): ConcreteClass#DataType = Nil 
} 
//... 
val a = DataType() 

+0

Это работает. Благодарю. Однако с этим я должен определить каждый метод List, чтобы делать то, что хочу, и это немного подробный. Очень хорошо иметь контроль над тем, что можно назвать тоже. Благодаря вашему ответу, я думаю, что получил общее решение для «может вызвать все методы List»: опубликовать его сейчас. Большое спасибо :) – Jean

Смежные вопросы