【问题标题】:How to case match a type variable enclosed in a generic type?如何大小写匹配包含在泛型类型中的类型变量?
【发布时间】:2016-06-05 16:32:52
【问题描述】:

我正在编写一个 Scala 子例程来从 2 个类型标签构造一个 TypeTag[Map[_<: a _ b>

tag1: TypeTag[Iterable[_<: A]]
tag2: TypeTag[Iterable[_<: B]]

上限是必要的,因为 A 和 B 都被声明为协变,而 TypeTag[T] 是不变的。

我正在尝试使用大小写匹配来获取 A 和 B 的隐式类型变量,但发现 Scala 中的类型模式匹配相对较周。即以下代码编译失败:

(tag1, tag2) match {
  case (tt1: TypeTag[Iterable[t1]], tt2: TypeTag[Iterable[t2]]) =>
    implicit val t1 = tt1
    implicit val t2 = tt2
    ScalaReflection.universe.typeTag[Map[t1, t2]]
}

因为 t1 和 t2 无法解析。我应该怎么做才能解决这个问题?

【问题讨论】:

    标签: scala reflection pattern-matching


    【解决方案1】:

    这简化为从TypeTag[Iterable[t1]] 获取TypeTag[t1]。这是可能的,但非常丑陋:https://stackoverflow.com/a/25691045/9204.

    所以你最终会得到类似(未经测试!):

    import scala.reflect.runtime.universe._
    
    def typeToTypeTag[T](
      tpe: Type,
      mirror: reflect.api.Mirror[reflect.runtime.universe.type]
    ): TypeTag[T] = {
      TypeTag(mirror, new reflect.api.TypeCreator {
        def apply[U <: reflect.api.Universe with Singleton](m: reflect.api.Mirror[U]) = {
          assert(m eq mirror, s"TypeTag[$tpe] defined in $mirror cannot be migrated to $m.")
          tpe.asInstanceOf[U#Type]
        }
      })
    }
    
    def argTypeTag[A](tag: TypeTag[_ /* Actually F[A] for some F */]): TypeTag[A] = 
      typeToTypeTag[A](tag.tpe.typeArgs.head)
    
    (tag1, tag2) match {
      case (tt1: TypeTag[Iterable[t1]], tt2: TypeTag[Iterable[t2]]) =>
        implicit val t1 = argTypeTag[t1](tt1)
        implicit val t2 = argTypeTag[t2](tt2)
        typeTag[Map[t1, t2]]
    }
    

    【讨论】:

      猜你喜欢
      • 2013-07-06
      • 1970-01-01
      • 2016-07-03
      • 1970-01-01
      • 1970-01-01
      • 2013-12-21
      • 1970-01-01
      • 1970-01-01
      • 2019-08-10
      相关资源
      最近更新 更多