【问题标题】:Scala: Lambda cannot be cast to ClassTag errorScala:Lambda 无法转换为 ClassTag 错误
【发布时间】:2018-11-20 05:57:44
【问题描述】:

我正在尝试将视图绑定(使用不推荐使用的绑定的动机将在下面介绍)与隐式 ClassTag 参数相结合。简而言之,这是我的类的层次结构(我省略了似乎无关紧要的代码,欢迎您指出是否需要):

abstract class BaseSort [T <% Ordered[T]]{
//some methods
}

我将其设为抽象类而不是特征,因为特征不支持上下文和视图边界。我选择 view over context 是因为前者支持隐式转换:

来自“不耐烦的 Scala”的第一版(第 234 页):

&lt;% 关系意味着可以通过隐式转换将 T 转换为 Comparable[T]

然后作为它的实现,我有一个 MergeSort 类:

//Segewick and Wayne's implementation re-written in Scala
class MergeSort [T <% Ordered[T]](implicit evidence: ClassTag[T]) extends BaseSort [T]{
  var aux: Array[T] = _

  def sort(a: Array[T]): Array[T] = {
    aux = new Array[T](a.length)
    sort(a, 0, a.length-1)
  }
...
}

类签名之前的注释行是不言自明的,但我认为这个字段var aux: Array[T] = _ 是我的问题开始的地方。如果我遵循算法的书,那么我不应该尝试从构造函数初始化它。

最后我有一个 MergeSort 实现的变体,它具有以下签名(它覆盖了 MergeSort 的排序方法):

class Ex2_2_12[T<% Ordered[T]](implicit evidence: ClassTag[T]) extends MergeSort[T]{
...
}

现在当我尝试运行这个测试时:

class Ex2_2_12Spec extends BaseSpec{

 ...

  "an array" should "at least be sorted" in {
    val test = "MERGEWITHSHELLSORTEXAMPLE".toCharArray
    val customMergeSort = new Ex2_2_12[Char]
    customMergeSort.sort(test)
    info(s"target array after sorting is ${test.toList}")
    assert(isSorted(test))
  }
}

这就是扔给我的东西 :-):

[info] an array
[info] - should at least be sorted *** FAILED ***
[info]   java.lang.ClassCastException: ca.vgorcinschi.algorithms_2.Ex2_2_12Spec$$Lambda$18483/698572900 cannot be cast to scala.reflect.ClassTag
[info]   at ca.vgorcinschi.algorithms_2.Ex2_2_12.<init>(Ex2_2_12.scala:21)
[info]   at ca.vgorcinschi.algorithms_2.Ex2_2_12Spec.$anonfun$new$2(Ex2_2_12Spec.scala:13)
[info]   at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
[info]   at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
[info]   at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[info]   at org.scalatest.Transformer.apply(Transformer.scala:22)
[info]   at org.scalatest.Transformer.apply(Transformer.scala:20)
[info]   at org.scalatest.FlatSpecLike$$anon$1.apply(FlatSpecLike.scala:1682)
[info]   at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
[info]   at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
[info]   ...

堆栈跟踪第 21 行中引用的是 Ex2_2_12 的签名。我尝试了两件事:

  • 使用复合绑定 (class Ex2_2_12[T&lt;% Ordered[T] with ClassTag[T]]) - 相同的错误
  • 删除 ClassTag 隐式参数 - 然后我得到上面引用的辅助字段 (Array[T]) 的错误,即没有提供 ClassTag。

我将继续调查,但如果有人能给我一个提示或方向,将不胜感激。

【问题讨论】:

    标签: scala casting type-conversion implicit


    【解决方案1】:

    在我的情况下,解决方案是(来自同一本书,但在 80 页之后)读取已弃用的视图边界并使用复合上下文边界:

    基类:

    abstract class BaseSort [T : Ordering]{
    
      ...
    
      def less(v: T, w: T):Boolean = {
        import Ordered._
        v < w
      }
    ...
    }
    

    一级升级:

    class MergeSort [T : ClassTag : Ordering] extends BaseSort [T]{
      var aux: Array[T] = _
    ...
    }
    

    和我测试所需的几乎相同的课程:

    class Ex2_2_12[T : ClassTag : Ordering] extends MergeSort[T]{...}
    

    【讨论】:

      猜你喜欢
      • 2019-12-31
      • 1970-01-01
      • 2022-01-26
      • 2022-01-20
      • 2014-02-03
      • 2021-08-21
      • 2021-11-18
      • 1970-01-01
      • 2022-01-25
      相关资源
      最近更新 更多