2014-06-22 101 views
1

我们有一个特质Foo和正在考虑的方法cast,需要一个类型参数A <: Foo和参数f: Foo并返回Some(f: A)如果f <: A,否则None类型:TypeTag包含抽象类型

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

如果Foo extendings将永远是通用的,那么附加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 

但是,如果抽象类型存在一些Foo会怎么样?等类

trait FooTyped extends Foo { 
    type T 
} 

然后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? 

这是因为ClassTag不关心的类型参数和抽象类型。

所以我们打算使用TypeTag来跟踪他们......但我不知道具体是怎么做的。

请帮我写完这篇文章:(

回答

2

ghik答案是正确的。作为补充,我提供了一种可能的方式来实现这一点:

有了这个辅助类:

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

你会得到这样的期望答案:

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 
+0

非常感谢你! –

2

有:

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

你将不仅需要TypeTag为目标类型ATypeTag的价值f在JVM对象不要在运行时携带完整的信息

+0

哦,这是有道理的:)谢谢! –