2013-03-13 6 views
1

Отказ от ответственности:Это вопрос о том, что возможно, а не то, что будет рекомендовано на практике.Структурные Тип Параметры в Scala Коллекции

Допустим, вы дали следующие классы:

case class point1(x: Int, y:Int) 
case class point2(x: Int, y:Int) 
case class point3(x: Int, y:Int) 

и у вас есть списки, содержащие некоторое количество каждого класса

val points1 = List[point1](/*Can be empty for this example*/) 
val points2 = List[point2]() 
val points3 = List[point3]() 

является возможность создать список структурного типа который может содержать все три типа точек, используя обычные методы, такие как ++, ::: или .union(..), не определяя общий признак, который распространяется на все классы, т.е.

var points: List[{def x: Int; def y: Int}] = 
    points1 ::: points2 ::: points3 

Я понимаю, что как указано выше, оператор ::: возвращает List[Product]. Я предполагаю, что это вопрос обеспечения правильных подсказок компилятора Scala, так как следующий код действительно производит список нужного типа:

var points: ListBuffer[{def x: Int; def y: Int}] = List[{def x: Int; def y: Int}]() 
points1.foreach(e => { 
    val p: {def x: Int; def y: Int} = e; 
    points.append(p); 
}) 
points2.foreach(e => { 
    val p: {def x: Int; def y: Int} = e; 
    points.append(p); 
}) 

Существуют ли какие-то намеки, я могу дать, чтобы помочь компилятору Scala, чтобы выбрать правильный тип для ::: и составить список указанного структурного типа?

+0

У вас есть ответ, но имейте в виду, что стоимость вызова метода (или доступ к свойству, что является одним и тем же) значительно выше при использовании структурного типа. –

+0

@RandallSchulz Спасибо, как я заявил в ** отказ от ответственности **, это не используется на практике, а просто мысленный эксперимент о том, что возможно с системой структурного типа Scala и выводом. Я понимаю, что сочетание структурной типизации, особенно с неявными преобразованиями, может иметь серьезные последствия для производительности. – Syllepsis

ответ

2
(points1 : List[{val x : Int; val y : Int}]) ::: points2 ::: points3 

Должно работать!

+0

Спасибо. Через несколько минут после публикации я нашел свою реальную проблему, которая не была связана с вопросом, который я задал выше. В реальном примере класс 'point3' не точно соответствует двум другим и полагается на неявные преобразования. Мне не хватало намека на то, чтобы вызвать неявное преобразование, которое вызывало ':::' возврат к использованию 'List [Product]' в качестве возвращаемого типа. Спасибо! – Syllepsis

0

Если вы хотите, чтобы написать следующий код:

var points: List[{def x: Int; def y: Int}] = 
points1 ::: points2 ::: points3 

Он работает:

implicit def typer[B >: A, A <: { def x: Int; def y: Int }](t: List[B]): List[A] = t 

var points: List[{def x: Int; def y: Int}] = 
points1 ::: points2 ::: points3 

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

  • Нет связанных вопросов^_^