如何解决编译时的类型错误:Any to T?
How can I resolve type error on compile: Any to T?
我有一个 json 元组序列化程序。它首先反映在 Tuple 上并构建一个函数,给定一个元组,它将 return (TypeAdapter, value) 对的列表。 (TypeAdapter 是一种呈现值的特定于类型的东西。)看起来像这样:
def extractTuple(p: Product): (Product)=>List[(TypeAdapter[_], Any)] = {
val reflected = reflectOnTuple(tupleClass) // extract a bunch of reflected metadata
val tupleFieldInfo = reflected.tupleFieldInfo
tupleFieldInfos match {
case 1 =>
(p: Product) =>
List( (getTypeAdapterFor(tupleFieldInfo(0)), p.asInstanceOf[Tuple1[_]]._1) )
case 2 =>
(p: Product) =>
List( (getTypeAdapterFor(tupleFieldInfo(0)), p.asInstanceOf[Tuple1[_]]._1),
(getTypeAdapterFor(tupleFieldInfo(1)), p.asInstanceOf[Tuple1[_]]._2) )
//... and so on to Tuple23
}
}
在 JSON 序列化程序中,我有一个 writeTuple() 函数,如下所示。理论上它应该按原样工作,但是......我在 fieldValue 上遇到编译错误,说它是 Any 类型,而预期的是 ?1.T.
TypeAdapter 看起来像:
trait TypeAdapter[T] {
def write[WIRE](
t: T,
writer: Writer[WIRE],
out: mutable.Builder[WIRE, WIRE]): Unit
}
class JsonWriter() {
def writeTuple[T](t: T, writeFn: (Product) => List[(TypeAdapter[_], Any)], out: mutable.Builder[JSON, JSON]): Unit = {
out += "[".asInstanceOf[JSON]
var first = true
writeFn(t.asInstanceOf[Product]).foreach { case (fieldTA, fieldValue) =>
if (first)
first = false
else
out += ",".asInstanceOf[JSON]
fieldTA.write(fieldValue, this, out) // <<-- this blows up (compile) on fieldValue because it's type Any, not some specific field Type
}
out += "]".asInstanceOf[JSON]
}
}
如何让我的 TypeAdapter 相信该字段是正确的类型?
尝试将类型模式与类型变量一起使用 tp
(lower-case)
class JsonWriter() extends Writer[JSON] {
def writeTuple[T](t: T, writeFn: (Product) => List[(TypeAdapter[_], Any)], out: mutable.Builder[JSON, JSON]): Unit = {
...
writeFn(t.asInstanceOf[Product]).foreach { case (fieldTA: TypeAdapter[tp], fieldValue) =>
...
fieldTA.write(fieldValue.asInstanceOf[tp], this, out)
}
...
}
}
或T
代替它
class JsonWriter() extends Writer[JSON] {
def writeTuple[T](t: T, writeFn: (Product) => List[(TypeAdapter[_], Any)], out: mutable.Builder[JSON, JSON]): Unit = {
...
writeFn(t.asInstanceOf[Product]).foreach { case (fieldTA: TypeAdapter[T], fieldValue) =>
...
fieldTA.write(fieldValue.asInstanceOf[T], this, out)
}
...
}
}
看来您实际上并没有在 writeTuple[T]
中使用 T
。也许你可以尝试单态 def writeTuple(t: Product...
此外,如果你想指定 (TypeAdapter[_], Any)
实际上是 (TypeAdapter[U], U)
在元组的两个元素中具有相同的 U
你可以尝试存在类型 (TypeAdapter[U], U) forSome {type U}
。所以试试
class JsonWriter() extends Writer[JSON] {
def writeTuple(t: Product, writeFn: (Product) => List[(TypeAdapter[U], U) forSome {type U}], out: mutable.Builder[JSON, JSON]): Unit = {
out += "[".asInstanceOf[JSON]
var first = true
writeFn(t).foreach { case (fieldTA, fieldValue) =>
if (first)
first = false
else
out += ",".asInstanceOf[JSON]
fieldTA.write(fieldValue, this, out)
}
out += "]".asInstanceOf[JSON]
}
}
Dmytro,你的答案非常接近!不幸的是,第一个或第二个选项都没有编译。我认为第三个会很好,除了......我实际上使用的是 Dotty 而不是 Scala,并且 Dotty 消除了存在类型。
所以我尝试了以下方法,它奏效了。它涉及修改 TypeAdapter,因为它知道它的类型:
trait TypeAdapter[T] {
type tpe = T
def write[WIRE](
t: T,
writer: Writer[WIRE],
out: mutable.Builder[WIRE, WIRE]): Unit
inline def castAndWrite[WIRE](
v: Any,
writer: Writer[WIRE],
out: mutable.Builder[WIRE, WIRE]): Unit =
write(v.asInstanceOf[tpe], writer, out)
}
从 JsonWriter 调用 castAndWrite() 可以调用 correctly-typed write() 机制。
我有一个 json 元组序列化程序。它首先反映在 Tuple 上并构建一个函数,给定一个元组,它将 return (TypeAdapter, value) 对的列表。 (TypeAdapter 是一种呈现值的特定于类型的东西。)看起来像这样:
def extractTuple(p: Product): (Product)=>List[(TypeAdapter[_], Any)] = {
val reflected = reflectOnTuple(tupleClass) // extract a bunch of reflected metadata
val tupleFieldInfo = reflected.tupleFieldInfo
tupleFieldInfos match {
case 1 =>
(p: Product) =>
List( (getTypeAdapterFor(tupleFieldInfo(0)), p.asInstanceOf[Tuple1[_]]._1) )
case 2 =>
(p: Product) =>
List( (getTypeAdapterFor(tupleFieldInfo(0)), p.asInstanceOf[Tuple1[_]]._1),
(getTypeAdapterFor(tupleFieldInfo(1)), p.asInstanceOf[Tuple1[_]]._2) )
//... and so on to Tuple23
}
}
在 JSON 序列化程序中,我有一个 writeTuple() 函数,如下所示。理论上它应该按原样工作,但是......我在 fieldValue 上遇到编译错误,说它是 Any 类型,而预期的是 ?1.T.
TypeAdapter 看起来像:
trait TypeAdapter[T] {
def write[WIRE](
t: T,
writer: Writer[WIRE],
out: mutable.Builder[WIRE, WIRE]): Unit
}
class JsonWriter() {
def writeTuple[T](t: T, writeFn: (Product) => List[(TypeAdapter[_], Any)], out: mutable.Builder[JSON, JSON]): Unit = {
out += "[".asInstanceOf[JSON]
var first = true
writeFn(t.asInstanceOf[Product]).foreach { case (fieldTA, fieldValue) =>
if (first)
first = false
else
out += ",".asInstanceOf[JSON]
fieldTA.write(fieldValue, this, out) // <<-- this blows up (compile) on fieldValue because it's type Any, not some specific field Type
}
out += "]".asInstanceOf[JSON]
}
}
如何让我的 TypeAdapter 相信该字段是正确的类型?
尝试将类型模式与类型变量一起使用 tp
(lower-case)
class JsonWriter() extends Writer[JSON] {
def writeTuple[T](t: T, writeFn: (Product) => List[(TypeAdapter[_], Any)], out: mutable.Builder[JSON, JSON]): Unit = {
...
writeFn(t.asInstanceOf[Product]).foreach { case (fieldTA: TypeAdapter[tp], fieldValue) =>
...
fieldTA.write(fieldValue.asInstanceOf[tp], this, out)
}
...
}
}
或T
代替它
class JsonWriter() extends Writer[JSON] {
def writeTuple[T](t: T, writeFn: (Product) => List[(TypeAdapter[_], Any)], out: mutable.Builder[JSON, JSON]): Unit = {
...
writeFn(t.asInstanceOf[Product]).foreach { case (fieldTA: TypeAdapter[T], fieldValue) =>
...
fieldTA.write(fieldValue.asInstanceOf[T], this, out)
}
...
}
}
看来您实际上并没有在 writeTuple[T]
中使用 T
。也许你可以尝试单态 def writeTuple(t: Product...
此外,如果你想指定 (TypeAdapter[_], Any)
实际上是 (TypeAdapter[U], U)
在元组的两个元素中具有相同的 U
你可以尝试存在类型 (TypeAdapter[U], U) forSome {type U}
。所以试试
class JsonWriter() extends Writer[JSON] {
def writeTuple(t: Product, writeFn: (Product) => List[(TypeAdapter[U], U) forSome {type U}], out: mutable.Builder[JSON, JSON]): Unit = {
out += "[".asInstanceOf[JSON]
var first = true
writeFn(t).foreach { case (fieldTA, fieldValue) =>
if (first)
first = false
else
out += ",".asInstanceOf[JSON]
fieldTA.write(fieldValue, this, out)
}
out += "]".asInstanceOf[JSON]
}
}
Dmytro,你的答案非常接近!不幸的是,第一个或第二个选项都没有编译。我认为第三个会很好,除了......我实际上使用的是 Dotty 而不是 Scala,并且 Dotty 消除了存在类型。
所以我尝试了以下方法,它奏效了。它涉及修改 TypeAdapter,因为它知道它的类型:
trait TypeAdapter[T] {
type tpe = T
def write[WIRE](
t: T,
writer: Writer[WIRE],
out: mutable.Builder[WIRE, WIRE]): Unit
inline def castAndWrite[WIRE](
v: Any,
writer: Writer[WIRE],
out: mutable.Builder[WIRE, WIRE]): Unit =
write(v.asInstanceOf[tpe], writer, out)
}
从 JsonWriter 调用 castAndWrite() 可以调用 correctly-typed write() 机制。