Scala绑定在类型参数

时间:2015-07-29 16:07:02

标签: scala types type-parameter

我有一个接受类型参数的类,我希望类上的方法被限制为遵循该参数化的参数。但是,当具体实例化类时,类型参数具有混合的其他特征,我想忽略该方法。具体地:

trait X {def str = "X"}
trait X1 extends X {def str = "X1"}
trait X2 extends X {def str = "X1"}

trait Y

class Foo[A <: X] { def do(a:A) = a.str}

val f = new Foo[X1 with Y]
val x1 = new X1 {}
val x2 = new X2 {}
val y = new Y {}

// I want this to compile
f.do(x1)
// and these to not compile
f.do(x2)
f.do(y)

目前三个最终语句都没有编译,但是我想在Foo.do方法上设置type参数,以便只编译第一个语句。我不知道如何从声明中“提取”A类型的适当部分。

1 个答案:

答案 0 :(得分:1)

我已经找到了一个解决方案,虽然它不是太优雅,而且我对其他人开放。因为,通过假设,我只会在我的X方法中使用do上的方法(因为它们是唯一可见的类型)我可以使用一个输入参数转换为适当的类型隐含如下:

trait X {def str = "X"}
trait X1 extends X {override def str = "X1"}
trait X2 extends X {override def str = "X1"}

trait Y

trait X {def str = "X"}

implicit def x2xWy[Xt <: X](x:Xt):Xt with Y = x.asInstanceOf[Xt with Y]

class Foo[A <: X] { def doIt[A1](a:A1)(implicit toA:(A1 => A)) = toA(a).str}

// this compiles
f.doIt(x1)
// and these do not
f.doIt(x2)
f.doIt(y)

也就是说,这种方法在几个方面仍然不是最理想的,即我们需要在编译时知道在运行时可能混入A的所有类型。此外,需要仔细管理隐含的范围,以确保它不会泄漏到可能导致问题的情况。