与路径预测混淆

时间:2018-06-01 23:43:59

标签: scala type-projection

这是我想要做的事情

class Bar[P](val x: P) { type Foo = P }
class Baz[R <: Bar[_]](bar: R) { val x: R#Foo = bar.x }

我们的想法是使用单个类型参数创建Baz,并且可以访问其中的两种类型。

但这不起作用:(

found   : Baz.this.x.type (with underlying type _$1)
required: _$1

听起来像“底层类型_ $ 1”正是我想要的,但是不能编译。 有没有办法在这里做我想要的?

更新

也许,我过度简化了用例。 比方说,Bar实际上是这样的:

trait Foo[T] { def doStuff(t: T) = ??? }
class Bar[P] extends Foo[P](val x: P) { type Foo = P }

和其他地方我有一个

 def fooX[T](x: T, foo: Foo[T]) = foo.doStuff(x)

我希望从Baz调用它:

 class Baz[R <: Bar[_]](bar: R) { fooX(bar.x, bar) }

感觉它应该有效:fooX参数将始终是正确的类型。但它没有编译,我想不出更好的解决方法,而不是将Baz两个类型参数,这似乎是多余的。

1 个答案:

答案 0 :(得分:1)

当您调用 df.unstack('Date') 时,编译器只能看到:

  • fooX(bar.x, bar)bar: Bar[_]
  • 相同
  • bar : Bar[X] forSome { type X },缩减为bar.x : X forSome { type X }

然后它无法证明bar.x: AnyAny中的X相同。但是,如果将未知类型绑定到变量forSome { type X },则编译器会看到:

  • p
  • bar: Bar[p]
  • bar.x : p适用。

因此,这有效:

fooX[p](bar.x, bar)

Outtakes(更新前尝试次数)

试图解决原始问题的两个片段,也许你在这里找到了一些有用的东西:

trait Foo[T] { def doStuff(t: T) = ??? }
class Bar[P](val x: P) extends Foo[P] { type Foo = P }

def fooX[T](x: T, foo: Foo[T]) = foo.doStuff(x)

class Baz[R <: Bar[_]](bar: R){
  bar match {
    case b: Bar[p] => fooX[p](b.x, b)
  }
}

class Bar[P](val x: P) { type Foo = P ; val y: Foo = x } class Baz[R <: Bar[_]](val bar: R) { val x: bar.Foo = bar.y } x联系起来的另一种方式:

Foo