我试图使用这种代码:
trait Outer {
type Inner
def f(x:Inner) : Void
}
object test {
def apply(o: Outer, i : Outer#Inner) : Void =
o.f(i)
}
我在最后一行中收到错误:
类型不匹配;发现:i.type(底层类型为Outer#Inner)需要:o.Inner
如果我将申请签名改为
def apply(o: Outer, i : o.Inner) : Void
然后我收到了一个错误:
非法依赖方法类型
是否有可能让这段代码有效?
答案 0 :(得分:5)
您可以利用依赖于方法的类型(请参阅示例中的What are some compelling use cases for dependent method types?)。 这将要求您使用2个参数列表:
trait Outer {
type Inner
def f(x:Inner): Unit
}
object test {
def apply( o: Outer )( i : o.Inner) { o.f(i) }
}
答案 1 :(得分:1)
但是imo
o.Inner
比Outer#Inner
更加丑陋。你能解释一下,使用前者而不是后者的用途是什么?编译器只能进行静态检查,因此o.Inner
应该等于o.type#Inner
,它应该(静态地)等于Outer#Inner
。我错过了什么吗?
原因如下。想象一下你有
class Outer1 extends Outer {
type Inner = Int
def apply(i: Int) { ... }
}
class Outer2 extends Outer {
type Inner = String
def apply(i: Int) { ... }
}
test.apply(new Outer1, "abc")
应该编译吗?显然不是,因为它会调用不存在的Outer1.apply(String)
。但是,test.apply(new Outer1, 1)
也无法编译(否则你会回到路径依赖类型)并且根本无法使用此apply
!