简体   繁体   English

包含抽象类型的类型的TypeTag

[英]TypeTag for a type containing an abstract type

We have a trait Foo and are thinking about a method cast that takes a type parameter A <: Foo and a parameter f: Foo and returns Some(f: A) if f <: A , else None : 我们有一个特质Foo和正在考虑的方法cast ,需要一个类型参数A <: Foo和参数f: Foo和返回Some(f: A)如果f <: A ,否则None

trait Foo
def cast[A <: Foo](f: Foo): Option[A] = ???

If Foo extendings will never be generic, then attaching a ClassTag is the conclusion: 如果Foo扩展永远不会是通用的,那么附加ClassTag就是结论:

def cast[A <: Foo : ClassTag](f: Foo) = f match {
  case f: A => Some(f)
  case _ => None
}
...
class Bar extends Foo
class Hoo extends Foo
println cast[Bar](new Bar) //→ Some(Bar)
println cast[Hoo](new Bar) //→ None

But what if there exists some Foo with an abstract type? 但是,如果存在一些具有抽象类型的Foo怎么办? Such like: 如:

trait FooTyped extends Foo {
  type T
}

Then the cast just gets destroyed at all: 然后,这些cast完全被摧毁了:

type FooT[A] = FooTyped{ type T = A }
...
val fint: FooT[Int] = new FooTyped{ type T = Int }
println cast[FooT[String]](fint) //→ Some(FooTyped) OH WHAT?

This happens because ClassTag doesn't care of type parameters and abstract types. 发生这种情况是因为ClassTag不在乎类型参数和抽象类型。

So we're going to use TypeTag that does keep track of them... But I don't know exactly how. 因此,我们将使用TypeTag来跟踪它们……但是我不知道具体如何。

Please help me finish writing this article :( 请帮我完成这篇文章:(

Having: 具有:

trait Foo
def cast[A <: Foo](f: Foo): Option[A] = ???

You're going to need not only the TypeTag for target type A but also TypeTag for value f . 您不仅需要目标类型ATypeTag ,还需要值f TypeTag Objects in JVM don't carry full type information in runtime. JVM中的对象在运行时不携带完整类型信息。

ghik answer is correct. ghik答案是正确的。 As a supplement I provide one possible way to achieve this: 作为补充,我提供了一种实现此目的的可能方法:

With this helper class: 使用此帮助器类:

class Caster[B : TypeTag](f: B) {
  def cast[A <: Foo : TypeTag] = 
    if(typeOf[B] <:< typeOf[A]) Some(f) else None
}

You would get the expected answers like this: 您将获得如下所示的预期答案:

println(new Caster(new Bar).cast[Bar]) //→ Some(Bar)
println(new Caster(new Bar).cast[Hoo]) //→ None
println(new Caster(fint).cast[FooT[String]]) //→ None

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM