scala - 与路径投影混淆
问题描述
这是我想要做的
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
,这似乎是多余的。
解决方案
当您调用fooX(bar.x, bar)
时,编译器只看到:
bar: Bar[_]
这与bar : Bar[X] forSome { type X }
bar.x : X forSome { type X }
,这减少到bar.x: Any
然后它无法证明与中Any
的相同。但是,如果将未知类型绑定到变量,则编译器会看到:X
forSome { type X }
p
bar: Bar[p]
bar.x : p
fooX[p](bar.x, bar)
适用。
因此,这有效:
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)
}
}
Outtakes(更新前尝试)
尝试解决原始问题的两个片段,也许你在这里找到一些有用的东西:
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
:
trait Br { type Foo ; val x: Foo }
class Bar[F](val x: F) extends Br { type Foo = F }
class Baz[R <: Br](val bar: R) {val x: bar.Foo = bar.x }
推荐阅读
- python - 如何使用spacy获得句子中两个单词之间的一对依赖关系?
- c - UART 不适用于 Linux 中的启动应用程序
- c# - Azure 认知服务 - 语音转文本:未检测到麦克风
- javascript - Onchange 事件从未使用 JSX 中的选择控件触发
- graphql - 有没有办法在 GraphQL 中过滤连接表中的元素?
- java - 问题“条目名称'META-INF/android.support.design_material.version'碰撞”Android工作室
- python - 在行列或对角线中找到 4 个
- python - 如何在 Python 中用新字母拆分字符串
- python - 从 pandas 数据框中创建一个“存在-不存在”矩阵
- json - Svelte - 想要热重载处理本地 json 数据文件