Scala:验证类参数在编译时不是trait的实例
在编译时,我想验证一个类参数是否不是一个特定trait T的实例。我知道如何在运行时使用Scala:验证类参数在编译时不是trait的实例,scala,shapeless,scala-macros,scala-reflect,Scala,Shapeless,Scala Macros,Scala Reflect,在编译时,我想验证一个类参数是否不是一个特定trait T的实例。我知道如何在运行时使用require或case match进行验证,但我想知道如何在编译时做到这一点,以防止用户提供某种类型的对象混合 我已经研究了scala宏/反射,但无法完全理解这一点 trait A trait B trait T abstract class C extends A with B case class P(c: C){ require(!c.isInstanceOf[T]) // how to do
require
或case match
进行验证,但我想知道如何在编译时做到这一点,以防止用户提供某种类型的对象混合
我已经研究了scala宏/反射,但无法完全理解这一点
trait A
trait B
trait T
abstract class C extends A with B
case class P(c: C){
require(!c.isInstanceOf[T]) // how to do this at compile time ?
}
// usage as below
object c1 extends C
object c2 extends C
object c3 extends C
object c4 extends C with T
val l = List(c1, c2, c3, c4).map(k => P(k)) // should fail at compile time
使用
列表
无法执行此操作。列表(c1、c2、c3、c4)
中的所有元素都将属于同一类型,即C
,其中一个元素的类型为C和T的信息将丢失
newc{}
,newc with T{}
是c1、c2、c3、c4
的运行时值,编译器在编译列表(c1、c2、c3、c4)
时无权访问它们
您可以使用HList
执行此操作。使用shapeless.Thank,它似乎无法处理扩展抽象类的单例对象。编译顺利完成。对不起,一开始我应该把我的问题描述得更好。我相信这可能不适用于单例对象,因为对单例对象的惰性计算。有什么解决办法吗?@bawejakunal懒惰的计算怎么可能与编译时相关?什么的变通办法?更好地描述您尝试的内容和获得的内容(编译错误等)@bawejakunal我想我已经在回答中解释了List
和HList
。这不能与列表
一起使用。你还有其他问题吗?谢谢,这很有效,不过我想知道,如果不使用这种投影仪,这是否可以工作。对于一个我正在努力添加插件的项目,该插件在短期内可能不可行。@bawejakunal是的,当然这可以在没有lambda:def noElementIsSubtypeOfT[L]类型的投影仪的情况下编写
def noElementIsSubtypeOfT[L <: HList](l: L)(implicit liftAll: LiftAll[* <:!< T, L]) = null
noElementIsSubtypeOfT(c1 :: c2 :: c3 :: HNil) // compiles
// noElementIsSubtypeOfT(c1 :: c2 :: c3 :: c4 :: HNil) // doesn't compile
def noElementIsSubtypeOfT[L <: HList : LiftAll[* <:!< T, *]](l: L) = null
case class P[U <: C](c: U)(implicit ev: U <:!< T)
P(c1) // compiles
P(c2) // compiles
P(c3) // compiles
// P(c4) // doesn't compile
case class P[U <: C : * <:!< T](c: U)