如何使用无形状在 Scala 中返回 cast 和 asInstanceOf 的结果



我有一个函数,可以使用无类型将 Scala 中的Something[Any]转换为Something[X]

import shapeless._
import shapeless.syntax.typeable._
def doCast[T: Typeable](v: Vector[Any]): T = v.cast[T].get

现在我想按索引访问列表:

val a = Vector[Any](1,2,3);
println(doCast[Vector[Int]](a)(1))

但这会引发一个异常:

/path/to/Test.scala:12: error: type mismatch;
found   : Int(1)
required: shapeless.Typeable[Vector[Any]]
println(doCast[Vector[Int]](a)(1))
^
one error found

但是,如果我先将此结果分配给变量,它会正确打印2

val a = Vector[Any](1,2,3);
val c = doCast[Vector[Int]](a)
println(c(1))

同样,如果我使用asInstanceOf转换结果,它可以正常工作:

val a = Vector[Any](1,2,3);
println(doCast[Vector[Int]](a).asInstanceOf[Vector[Int]](1));

我可以创建一个返回可索引结果的函数吗?

我尝试这样做,但我的尝试没有奏效:

def doCast2[T](v: Vector[Any]): T = doCast(v).asInstanceOf[T]

给出此错误:

/path/to/Test.scala:10: error: diverging implicit expansion for type shapeless.Typeable[T]
starting with method inrTypeable in object Typeable
def doCast2[T](v: Vector[Any]): T = doCast(v).asInstanceOf[T]
^
one error found

def doCast2[T](v: Vector[Any]): T = doCast[T](v).asInstanceOf[T]

给出此错误:

/path/to/Test.scala:10: error: 
class type required but T found
def doCast2[T](v: Vector[Any]): T = doCast[T](v).asInstanceOf[T]
^
one error found

问题似乎是脱糖后doCast的实际签名是从以下转换而来的:

def doCast[T: Typeable](v: Vector[Any]): T

def doCast[T](v: Vector[Any])(implicit ev1: Typeable[T]): T

所以当这样称呼它时

doCast[Vector[Int]](a)(1)

您正在 Typeable[T] 的位置传递 1。

最简单的解决方案是直接指定参数:

doCast[Vector[Int]](a)(implicitly)(1)

或者在doCast之后对向量使用单独的val

最新更新