2

这似乎是一个简单的事情,但我无法理解它......

这编译:

object CanFoo1 {
  def foo(): Unit = {
    println("Yup, I can foo alright")
  }
}

object CanFoo2 {
  def foo(): Unit = {
    println("And I can foo with the best")
  }
}

trait A {
  type CanFoo = { def foo(): Unit }
  def fooers: Seq[CanFoo]
}

class B extends A {
  def fooers = Seq(
    // CanFoo1, // <- won't compile when this is uncommented
    CanFoo2
  )
}

但取消注释该// CanFoo1,行给出:

error: type mismatch;
found   : Seq[Object]
required: Seq[B.this.CanFoo]
   (which expands to)  Seq[AnyRef{def foo(): Unit}]
def fooers = Seq(
              ^
one error found

所以看起来编译器理解一个只包含一个元素Seq(CanFoo2)(或Seq(CanFoo1))的集合是正确的类型,但是当两个对象都在集合中时它放弃了吗?我在这里做错了什么?

4

1 回答 1

2

所以看起来编译器理解一个只包含一个元素Seq(CanFoo2)(或Seq(CanFoo1))的集合是正确的类型,但是当两个对象都在集合中时它放弃了吗?我在这里做错了什么?

当您将CanFoo1or传递CanFoo2Seqapply 时,序列被推断为 typeCanFoo1.typeCanFoo2.type分别,它不被推断为 type CanFoo

当您将这两个元素都传递给 时Seq,编译器会尝试寻找可以有效推断的通用类型以使代码编译,并且它唯一可以找到的类型是Object,但fooers据说是 type Seq[CanFoo],因此编译器叫喊。

您可以通过显式编写集合的类型来帮助编译器:

class B extends A {
  def fooers = Seq[CanFoo](
    CanFoo1,
    CanFoo2
  )
}
于 2016-08-11T13:05:36.673 回答