0

我有一种感觉,我面临的问题与Scala 的类型擦除有关,但作为一个新手,我不能把手指放在它上面。在这里需要一些帮助。

首先,代码:

    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]) { ... }

您显示的代码创建了一个类和特定类型C。当您稍后编写class ContainerOfC[C]时,这C是一个可以由任何其他标识符命名的类型参数。这与定义class ContainerOfC[A]where与前面代码中定义A的类/类型没有任何关系相同。C在您的示例中,类型参数C将隐藏之前定义的类的名称......错误消息表明C没有值i,这是因为编译器引用的C不是您所想的相同。

编辑:让您快速知道我们是否在同一页面上而不会陷入其他编译错误,这里有一些编辑可以使代码编译并使用更常用的缩进和大括号样式:

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 回答