【问题标题】:Pattern Matching on Generic Trait's Parameterized Type泛型特征参数化类型的模式匹配
【发布时间】:2015-01-09 19:05:56
【问题描述】:

鉴于以下特征:

trait Foo[_ <: Product] {}

如何对 Foo 的泛型类型进行模式匹配?

换句话说,有没有办法在不使用运行时反射的情况下获得Foo_

【问题讨论】:

  • 我怀疑您即使在运行时也能获得该信息。到那时,这些信息很可能已被完全删除。
  • 那么,我上面的代码不是idiomatic吗?这种方法有通用的惯用模式吗?
  • 好吧,我不清楚你想要达到什么目的。也许使用ClassTags 或Class 对象可以部分保存类型信息,但在这种情况下,我不会使用存在类型(_)作为类型参数,而是使用命名类型(例如T) .

标签: scala


【解决方案1】:

_作为类型参数的全部意义在于指定类型为未知

【讨论】:

  • 我不确定这是否真的有资格作为答案。这对我来说更像是一个评论。像这样的事情可能会引起反对,所以你应该考虑切换它......
  • 好的,答案是“不,没有办法”。那个更好吗? :)
  • 是的,这是可能的。请参阅我不情愿发布的答案(因为它是重复的)。
  • @cmbaxter:您的回答是关于另一个问题。试试val fooBar: Foo[_ <: Product] = new Foo[Bar]{}; checkType(foo)
【解决方案2】:

这是可能的,我仍然认为这是我评论中提到的重复,但我想展示你如何做到这一点。原始答案归功于 om-nom-nom:

  trait Foo[_ <: Product]

  case class Bar(i:Int)
  case class Baz(s:String)  

  val fooBar = new Foo[Bar]{}
  val fooBaz = new Foo[Baz]{}

  checkType(fooBar)
  checkType(fooBaz)

  def checkType[T <: Product : TypeTag](foo:Foo[T]){
    foo match{
      case f if typeOf[T] <:< typeOf[Bar] => println("its a bar")
      case f if typeOf[T] <:< typeOf[Baz] => println("its a baz")
    }
  }

【讨论】:

  • 但是TypeTag 依赖于运行时,而不是编译时?
  • 两者。它确保在编译时提供给checkType 的所有Foos 都存在一个类型标记。然后在运行时类型标签使通常被擦除的信息可用。
  • Haskell 如何处理这种情况?
  • 没有线索。我不是 Haskell 人。
  • @KevinMeredith,Haskell 首先没有子类型。存在类型存在,但您只是无法提取隐藏在存在类型中的具体类型。你只能使用 typeclass 方法,如果存在上存在任何 typeclass 边界。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-30
  • 2021-02-24
  • 1970-01-01
  • 1970-01-01
  • 2015-10-02
  • 1970-01-01
  • 2018-06-20
相关资源
最近更新 更多