0

私が直面している問題は、Scala のType Erasureに関係しているように感じますが、初心者としては指を置くことができません。ここで助けが必要です。

まず、コード:

    class C (val i: Int) {
          def mkString() = { println("C.i =" + this.i) }

    object C {
               implicit val cOrdering = new Ordering [C] 
               {
                   def compare (a: C, b: C)= 
                   {
                        a.i compare b.i;
                   }
               }

次に、クラス 'C' のコレクションを保持する別のクラスを次のように作成します。

    class  ContainerOfC [C] (s:Int) (implicit ordering: cOrdering[C]) {

               var internalCollection = new TreeSet[C]()

               def + (c:C): ContainerOfC [C] = {
                   this.internalCollection += c
                   this
               }

               def mkStringOfElems () = {

                   val y = this.internalCollection.toList

                   println (y.head.i) // <--- Problem here

                }

            }

これはREPLが私に言うことです:

error: value i is not a member of type parameter C
                                    println(y.head.i)
                                                   ^

そこにある「y」のタイプを確認しました。これは List[C] です。もしそうなら、なぜ「i」へのアクセスが許可されていないのですか? 構築パラメータならいいけど、valだからメンバー変数として扱えるんじゃないの?

私はフォーラムで他の関連する投稿をいくつか見てきましたが、マニフェストとタイプタグはここから抜け出す方法として考えられます。しかし、この単純なユースケースでそのレベルに行く必要があるかどうかはわかりません。

4

1 に答える 1

2

これは、「そこにいた、それをやった」という奇妙で親しみのある感覚を持っています。

これを変更してみてはどうでしょうか。

class  ContainerOfC [C] (s:Int) (implicit ordering: cOrdering[C]) { ... }

宣言に型パラメータなしでこれに:C

class  ContainerOfC(s:Int) (implicit ordering: cOrdering[C]) { ... }

あなたが示したコードは、 class と特定の type を作成しましたC。後で書くclass ContainerOfC[C]と、それCは他の識別子で名前を付けることができる型パラメーターです。これは、前のコードで定義されたクラス/型とは何の関係もないclass ContainerOfC[A]whereを定義するのと同じです。あなたの例では、型パラメーターは以前に定義されたクラスの名前を隠します...エラーメッセージは、値がないことを示しています。これは、コンパイラーがあなたが考えているものと同じものを参照していないためです。ACCCiC

編集: 他のコンパイル エラーに悩まされずに同じページにいる場合にすぐにわかるように、コードをコンパイルし、より一般的に使用されるインデントとブレース スタイルを使用するためのいくつかの編集を次に示します。

class C(val i: Int) {
  def mkString() = println("C.i =" + this.i)
}

object C {
  implicit val cOrdering = new Ordering[C] {
    def compare(a: C, b: C) = a.i compare b.i
  }
}

class ContainerOfC(s: Int)(implicit ordering: Ordering[C]) {
  var internalCollection = new collection.mutable.TreeSet[C]()

  def +(c: C): ContainerOfC = {
    this.internalCollection += c
    this
  }

  def mkStringOfElems() = {
    val y = this.internalCollection.toList
    println(y.head.i)
  }
}
于 2013-02-09T04:30:32.100 に答える