Как импортировать внутренние классы без зависимости от пути в Scala? - PullRequest
5 голосов
/ 23 января 2012

TL & DR: Можно ли (локально?) Отключить ввод с использованием пути? Я хотел бы выпустить один оператор импорта, похожий на import x._, но чтобы C ссылался на X#C, а не x.C (X является типом x)?

У меня есть куча типов:

class Button[M] { ... }
class Label[M] { ... }
...

И я использую их вместе, передавая всем один и тот же аргумент типа:

class UseSite[M] (
   btn1 : Button[M]
 , btn2 : Button[M]
 , lbl1 : Label[M]) {
  ...
}

Я подумал, что было бы неплохо упаковать все эти типы, так что мне нужно только один раз передать параметр типа:

class Swing[M] {
  class Button { ... }
  class Label { ...}
}

Тогда на сайте использования я бы хотел сделать это:

class WithSwing[M] {
  val swing = new Swing[M]
  import swing._
  class UseSite(
     btn1 : Button
   , btn2 : Button
   , lbl1 : Label) {
    ...
  }
}

Однако это не работает должным образом из-за пути, зависящего от пути: Button относится к swing.Button вместо Swing[M]#Button, поэтому внешнему коду очень трудно передать правильные аргументы конструктору UseSite.

Есть ли хороший способ сделать Button относящимся к Swing[M]#Button вместо swing.Button?

Ответы [ 2 ]

4 голосов
/ 23 января 2012

Если предположить, что зависимости пути действительно случайны, то вместо того, чтобы прогонять проекции типа по всей базе кода, вы можете попробовать что-то вроде этого,

class Button[M]
class Label[M]

trait Swing[M] {
  type ButtonM = Button[M]
  type LabelM = Label[M]
}

class WithSwing[M] {
  val swing = new Swing[M] {}
  import swing._
  class UseSite(btn1 : ButtonM, btn2 : ButtonM, lbl1 : LabelM)
}

Снаружи WithSwing использование будет выглядеть,

val ws = new WithSwing[String]
import ws.swing._
new ws.UseSite(new ButtonM {}, new ButtonM {}, new LabelM {})

Наследование несколько увеличивает краткость,

class WithSwing[M] extends Swing[M] {
  class UseSite(btn1 : ButtonM, btn2 : ButtonM, lbl1 : LabelM)
}

// Usage ...
val ws = new WithSwing[String]
import ws._
new ws.UseSite(new ButtonM {}, new ButtonM {}, new LabelM {})
3 голосов
/ 23 января 2012

Кто-то может представить что-то вроде

import Swing[M]#_

для переноса всех членов типа типа Swing[M] в область действия, но этого не существует (import ожидает значение, а не тип). Для практических целей, как насчет псевдонима типа для уменьшения котельной пластины,

type S = Swing[M]
val b: S#Button = ... // Shorter than Swing[M]#Button
...