如何在编译时要求类型参数是特征(而不是 class 或其他类型值)?
How to require at compile time that a type parameter be a trait (and not a class or other type value)?
我正在寻找通用参数 T
的某种上限,以确保 T
是一个特征。
class Foo
trait Bar
def f[A ??? IsATrait] = ???
// f[Foo] Won't compile
f[Bar] // this is fine
Is it possible to require at compile time that a type parameter is a trait (and not a class or other type value)?
没有
尝试
typeOf[Bar].typeSymbol.asClass.isTrait // true
typeOf[Foo].typeSymbol.asClass.isTrait // false
编译时
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
trait IsATrait[A]
object IsATrait {
implicit def materialize[A]: IsATrait[A] = macro impl[A]
def impl[A: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
import c.universe._
val tpA = weakTypeOf[A]
if (tpA.typeSymbol.asClass.isTrait)
q"new IsATrait[$tpA] {}"
else c.abort(c.enclosingPosition, s"$tpA is not a trait")
}
}
def f[A: IsATrait] = ???
f[Bar] // compiles
f[Foo]
//Information: IsATrait.materialize is not a valid implicit value for IsATrait[Foo] because:
// hasMatchingSymbol reported error: Foo is not a trait
//
//Error: could not find implicit value for evidence parameter of type IsATrait[Foo]
//
//Error: not enough arguments for method f: (implicit evidence: IsATrait[Foo])Nothing.
// Unspecified value parameter evidence.
我正在寻找通用参数 T
的某种上限,以确保 T
是一个特征。
class Foo
trait Bar
def f[A ??? IsATrait] = ???
// f[Foo] Won't compile
f[Bar] // this is fine
Is it possible to require at compile time that a type parameter is a trait (and not a class or other type value)?
没有
尝试
typeOf[Bar].typeSymbol.asClass.isTrait // true
typeOf[Foo].typeSymbol.asClass.isTrait // false
编译时
import scala.language.experimental.macros
import scala.reflect.macros.whitebox
trait IsATrait[A]
object IsATrait {
implicit def materialize[A]: IsATrait[A] = macro impl[A]
def impl[A: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
import c.universe._
val tpA = weakTypeOf[A]
if (tpA.typeSymbol.asClass.isTrait)
q"new IsATrait[$tpA] {}"
else c.abort(c.enclosingPosition, s"$tpA is not a trait")
}
}
def f[A: IsATrait] = ???
f[Bar] // compiles
f[Foo]
//Information: IsATrait.materialize is not a valid implicit value for IsATrait[Foo] because:
// hasMatchingSymbol reported error: Foo is not a trait
//
//Error: could not find implicit value for evidence parameter of type IsATrait[Foo]
//
//Error: not enough arguments for method f: (implicit evidence: IsATrait[Foo])Nothing.
// Unspecified value parameter evidence.