案例类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

回到顶部