抽象成员类型的值

时间:2013-05-30 10:17:27

标签: scala type-members

我试图使用这种代码:

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

然后我收到了一个错误:

  

非法依赖方法类型

是否有可能让这段代码有效?

2 个答案:

答案 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.InnerOuter#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