通过使用宏禁止某些情况来实现“有效的类型安全”

问题描述

问题

在我的一个 previous question 中,我提供了一个具有以下模式匹配的示例

class A

class B

sealed trait Test {
  type Meta
}

case class Test1() extends Test {
  type Meta = A
}
case class Test2() extends Test {
  type Meta = B
}

case class Info[T <: Test](t: T,m: T#Meta)

val t: Info[_ <: Test] = ???
t match {
  case Info(t: Test1,a: Test1#Meta) =>
    println("1")
  case Info(t: Test2,a: Test2#Meta) =>
    println("2")
}

代码编译时出现以下警告:

match may not be exhaustive.
It would fail on the following inputs: 
Info((x: _$2 forSome x not in (Test1,Test2)),(x: _$2#Meta forSome x not in (A,B))),Info((x: _$2 forSome x not in (Test1,??),A()),B()),Info(??,Info(Test1(),Info(Test2(),A())

正如 Oleg Pyzhcov 中对 their answer 的大量解释,确实有可能构造一个无法匹配的值。

我的解决方

所以我目前想到的解决方案是用一个简单的宏来禁止这样的对象创建。这是:

object Info {
  def apply[T <: Test](t: T,m: T#Meta): Info[T] = macro applyImpl[T]

  def applyImpl[T <: Test](c: blackBox.Context)(t: c.Expr[T],m: c.Expr[T#Meta]): c.Expr[Info[T]] = {
    import c.universe._


    val sourceType = weakTypeTag[T].tpe
    if (!sourceType.typeSymbol.isClass || !sourceType.typeSymbol.isFinal) {
      c.abort(
        c.enclosingPosition,s"Creating is allowed for specific types only"
      )
    }

    //... create an object
  }
}

有了这样的 apply 实现,就不可能再构造这样的对象了。

问题:在使用此类 apply 实现时抑制编译器发出的警告是否可靠?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)