2017-12-03 8 views
4

ケースクラスが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) 
} 

これは特にケースクラスは、デフォルトでProductを拡張し、これproductIteratorを持っていながら、彼らはIterableを延長すると仮定されていないことを考えると、むしろ不幸と思われます。

これはScalaコンパイラのバグですか?

答えて

2

これはScalaコンパイラのバグですか?

いいえ、これは仕様(section §5.3.2、強調鉱山)で定義された動作である:

同じメソッドの定義がない限り、すべてのケースクラスは暗黙的クラス scala.AnyRefのいくつかのメソッドの定義をオーバーライド既にケースクラス自体に が与えられているか、同じメソッドの具体的な定義が であり、AnyRefとは異なるケースクラスの基本クラスに与えられています。特に :

  • 方法toString:文字列 クラスの名前と、その要素を含む文字列表現を返します。次のtoStringオーバーライドありTraversableLike、継承Iterableの結果であることがわかり何

:あなたはXprint:jvmの下でコンパイルした場合にさらに

override def toString = mkString(stringPrefix + "(", ", ", ")") 

は、あなたは、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(); 
} 
0

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 + "(", ",", ")") 
} 
関連する問題