Scala:Lambda 无法转换为 ClassTag 错误
Scala: Lambda cannot be cast to ClassTag error
我正在尝试将视图绑定(下面将介绍使用已弃用绑定的动机)与隐式 ClassTag 参数。下面简单介绍一下我的classes的层次结构(我省略了看似无关紧要的代码,如有需要欢迎指出):
abstract class BaseSort [T <% Ordered[T]]{
//some methods
}
我将其设为抽象 class 而不是特征,因为特征不支持上下文和视图边界。我选择视图而不是上下文,因为前者支持隐式转换:
自 "Scala for the Impatient" 第一版(第 234 页):
The <%
relation means that T can be converted to a Comparable[T] through an implicit conversion
然后作为它的一个实现,我有 class 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)
}
...
}
class 签名之前的注释行是不言自明的,但我认为这个字段 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$$Lambda483/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(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.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<% Ordered[T] with ClassTag[T]]
) -同样的错误
- 删除 ClassTag 隐式参数 - 然后我得到上面引用的辅助字段 (Array[T]) 的错误,没有提供 ClassTag。
我会继续调查,但如果有人能给我提示或指导,我将不胜感激。
我的解决方案是(来自同一本书,但在 80 页之后)阅读已弃用的视图边界并使用复合上下文边界:
基础class:
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 几乎完全相同:
class Ex2_2_12[T : ClassTag : Ordering] extends MergeSort[T]{...}
我正在尝试将视图绑定(下面将介绍使用已弃用绑定的动机)与隐式 ClassTag 参数。下面简单介绍一下我的classes的层次结构(我省略了看似无关紧要的代码,如有需要欢迎指出):
abstract class BaseSort [T <% Ordered[T]]{
//some methods
}
我将其设为抽象 class 而不是特征,因为特征不支持上下文和视图边界。我选择视图而不是上下文,因为前者支持隐式转换:
自 "Scala for the Impatient" 第一版(第 234 页):
The
<%
relation means that T can be converted to a Comparable[T] through an implicit conversion
然后作为它的一个实现,我有 class 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)
}
...
}
class 签名之前的注释行是不言自明的,但我认为这个字段 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$$Lambda483/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(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.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<% Ordered[T] with ClassTag[T]]
) -同样的错误 - 删除 ClassTag 隐式参数 - 然后我得到上面引用的辅助字段 (Array[T]) 的错误,没有提供 ClassTag。
我会继续调查,但如果有人能给我提示或指导,我将不胜感激。
我的解决方案是(来自同一本书,但在 80 页之后)阅读已弃用的视图边界并使用复合上下文边界:
基础class:
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 几乎完全相同:
class Ex2_2_12[T : ClassTag : Ordering] extends MergeSort[T]{...}