【问题标题】:Scala bound on part of a type parameterScala 绑定在类型参数的一部分上
【发布时间】:2015-10-20 17:51:13
【问题描述】:

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

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)

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

【问题讨论】:

  • 我认为没有这样的工具可以拆分复合类型。
  • 我不认为你能得到的最接近的可能是 (imo) class Foo[A &lt;: X] { def func[B &gt;: A &lt;: X ](b:B) = b.str } 仍然包括 f.do(x2)

标签: scala types type-parameter


【解决方案1】:

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

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 的类型。此外,需要仔细管理隐式的范围,以确保它不会泄露到可能导致问题的情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-18
    • 2011-03-05
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多