Scala Case类toString与Iterable特性纠缠在一起?

Scala Case类toString与Iterable特性纠缠在一起?,scala,Scala,似乎当一个case类扩展了Iterable[T]时,toString方法就改变了 case class MyPoint(x: Int, y: Int) case class MyOtherPoint(x: Int, y: Int) extends Iterable[Double] { def iterator: Iterator[Double] = Iterator.fill(4)(1.0) } object Main extends App { val my_pt = MyPoin

似乎当一个case类扩展了
Iterable[T]
时,
toString
方法就改变了

case class MyPoint(x: Int, y: Int)

case class MyOtherPoint(x: Int, y: Int) extends Iterable[Double] {
  def iterator: Iterator[Double] = Iterator.fill(4)(1.0)
}

object Main extends App {
  val my_pt = MyPoint(4,5)
  println(my_pt) // MyPoint(4,5)
  // println(my_pt.iterator) // ERROR, iterator is not a member of MyPoint
  val my_other_pt = MyOtherPoint(4, 5)
  println(my_other_pt) // MyOtherPoint(1.0, 1.0, 1.0, 1.0)
  println(my_other_pt.productIterator.toList) // List(4, 5)
}
这似乎很不幸,特别是考虑到case类在默认情况下扩展了
Product
,因此具有
productIterator
,它们不应该扩展
Iterable

这是Scala编译器中的错误吗

这是Scala编译器中的错误吗

不,这是规范中定义的行为(,强调我的):

每个case类都隐式重写类的某些方法定义
scala.AnyRef
除非已经给出了相同方法的定义 在case类本身或同一方法的具体定义中 在与AnyRef不同的case类的某些基类中给出。 特别是:

  • 方法
    toString
    :String返回包含 类及其元素的名称
您看到的是
Iterable
继承
TraversableLike
的结果,它具有以下
toString
覆盖:

override def toString = mkString(stringPrefix + "(", ", ", ")")
此外,如果您在
Xprint:jvm
下编译,您可以看到
MyOtherPoint
继承的许多方法,包括重写的
toString

case class MyOtherPoint extends Object with Iterable with Product with Serializable {
  // removed all other methods for brevity
  override def toString(): String = MyOtherPoint.super.toString();
}

您可以使用以下命令重新定义
toString
方法:

case class MyOtherPoint(x: Int, y: Int) extends Iterable[Double] {
  def iterator: Iterator[Double] = Iterator.fill(4)(1.0)
  override def toString(): String =
    productIterator.mkString(productPrefix + "(", ",", ")")
}