案例类toString与Iterable特征纠缠?
看起来,如果案例类延伸Iterable[T]
,则toString
方法发生更改。案例类toString与Iterable特征纠缠?
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编译器中的错误吗?
不,这是(section §5.3.2,重点煤矿)在规范中定义的行为:
每个案例类隐式覆盖类的一些方法定义
scala.AnyRef
除非同一方法的定义是已经在案例类本身给出了 ,或者在与AnyRef不同的案例类的某些基类中给出了相同方法 的具体定义。 特别是:
- 方法
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 + "(", ",", ")")
}
以上是 案例类toString与Iterable特征纠缠? 的全部内容, 来源链接: utcz.com/qa/259326.html