如何在Scala中导入内部类而不需要路径依赖?

5

简述:是否可能(本地)禁用路径相关的类型?我想发出一个类似于import x._的单个导入语句,但是要使C指向X#C而不是x.C(其中Xx的类型)?

我有一堆类型:

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

将“val swing”重命名为其他名称(以消除导入歧义)是否可行? - Rogach
为什么不通过将类放在一个对象内而不是另一个类内来避免这个问题呢? - Daniel C. Sobral
Daniel,因为对象不能有参数。 - Rotsor
Rogach,我想不是这样的。我不知道你在说什么歧义。 - Rotsor
2个回答

4

假设路径依赖确实是意外的,那么你可以尝试像这样操作,而不是在整个代码库中跟踪类型投影:

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

有人可能会想象出类似以下的情景:

import Swing[M]#_

为了将类型Swing[M]的所有成员引入作用域,但是这种方式并不存在(import需要一个值而不是一个类型)。为了实际目的,可以使用类型别名来减少样板代码。
type S = Swing[M]
val b: S#Button = ... // Shorter than Swing[M]#Button

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接