Scala Case类toString与Iterable特性纠缠在一起?
似乎当一个case类扩展了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
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类的某些基类中给出。
特别是:
- 方法
:String返回包含 类及其元素的名称toString
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 + "(", ",", ")")
}