2013-02-25 39 views
1

我有下面的代碼,用Scala編寫2.10.0:是否有可能實例化一個類的實例,並將其作爲參數傳遞給Scala中的通用特徵?

trait A[T <: B] { 
    self : { def foo() } => 

    val action :()=>Unit = this.foo _ 
    //wanna make default for this 
    val construction : String=>T 

    def bar()(implicit x : String) : T = { 
    action() 
    val destination = construction(x) 
    destination.baz() 
    destination 
    } 
} 

trait B { def baz() {} } 

class Xlass { def foo() {} } 

class Klass(a : String)(implicit val x : String) extends B { 
    val f = new Xlass with A[Klass] { 
     //boilerplate! 
     val construction = new Klass(_) 
    } 
} 

implicit val x = "Something" 
val destination = new Klass("some a").f.bar() 

我想知道,是否有可能作出construction默認,如val construction = new T(_)? 我已經嘗試了幾個選項,但沒有一個適用於此代碼的所有特性,例如使用類型邊界,含義和結構類型。至於我能得到的是這一點,但它失敗scala.ScalaReflectionException: free type T is not a class

import reflect.runtime.universe._ 
val tT = weakTypeTag[T] 
... 
val privConstruction = 
    x : String => 
    runtimeMirror(tT.mirror.getClass.getClassLoader) 
    //fails here with scala.ScalaReflectionException: free type T is not a class 
    .reflectClass(tT.tpe.typeSymbol.asClass) 
    .reflectConstructor(tT.tpe.members.head.asMethod)(x).asInstanceOf[T] 
+1

什麼是TT?請提供完整的片段。 – 2013-02-25 09:55:23

+0

@EugeneBurmako修正:) – Lakret 2013-02-25 11:16:11

+0

這裏只是一個類型參數,斯卡拉不知道任何關於。這是reflectionClass暗示的。要將關於T的信息從調用網站傳播到被調用者,您需要使用TypeTag或WeakTypeTag上下文綁定註釋T,如'class C [T:TypeTag]'中所示。不幸的是,特性不支持上下文邊界,所以你必須解決。 – 2013-02-25 14:37:21

回答

1

所以,最後,我做到了:

trait A[T <: B] { 
    self : { def foo() } => 

    val action :()=>Unit = this.foo _ 
    def construction(x: String)(implicit tag : reflect.ClassTag[T]) : T = { 
    tag.runtimeClass.getConstructor(classOf[String], classOf[String]).newInstance(x, x).asInstanceOf[T] 
    } 

    def bar()(implicit x : String, tag : reflect.ClassTag[T]) : T = { 
    action() 
    val destination = construction(x) 
    destination.baz() 
    destination 
    } 
} 

trait B { def baz() {} } 

class Xlass { def foo() {} } 

class Klass(a : String)(implicit val x : String) extends B { 
    val f = new Xlass with A[Klass] 
} 

implicit val x = "Something" 
val destination = new Klass("some a").f.bar() 
相關問題