У меня есть следующий код, написанный на 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]
Что такое Tt? Предоставьте полный фрагмент. –
@EugeneBurmako Fixed :) – Lakret
T вот только параметр типа, о котором Scala ничего не знает. Это то, на что намекает рефлексия. Чтобы распространять информацию о Т от сайтов вызовов до вызываемых лиц, вам необходимо аннотировать Т с привязкой к типу TypeTag или WeakTypeTag, как в 'class C [T: TypeTag]'. К сожалению, границы контекста не поддерживаются для признаков, поэтому вам придется работать. –