Scala中泛型类型的模式匹配

Posted

技术标签:

【中文标题】Scala中泛型类型的模式匹配【英文标题】:Pattern matching on generic type in Scala 【发布时间】:2014-01-22 14:10:49 【问题描述】:

我有如下所示的 scala 函数:

现在,取决于 T 的类型(在我的情况下,它可以是 DoubleBooleanLocalDate), 我需要在ob 上应用函数。像这样的东西(我知道代码没有意义,但我试图传达我的意思):

def X[T](ob: Observable[T]): Observable[T] = 
    //code  
    T match 
    case Double => DoSomething1(ob:Observable[Double]):Observable[Double]
    case Boolean => DoSomething2(ob:Observable[Boolean]):Observable[Boolean]
    case LocalDate => DoSomething3(ob:Observable[LocalDate]):Observable[LocalDate]
    

考虑到 Scala 的 Erasure 属性,是否可以以某种方式使用反射来完成工作?有没有可能?

【问题讨论】:

t: T(例如您要匹配的变量)来自哪里? @om-nom-nom 我希望编辑清楚 你见过***.com/questions/1094173/…吗? @om-nom-nom 那么,在我的情况下,你建议我做什么? 这听起来更像是您可以通过继承和多态来解决的问题。您可以使用常规重载或子类化。如果没有别的,看看蛋糕图案,最后是磁铁图案。使用磁铁模式,您可以灵活地选择您的实现。我不确切知道您要做什么,所以我无法举出更具体的例子。 spray.io/blog/2012-12-13-the-magnet-pattern 【参考方案1】:

如果您使用的是 2.10+,我会使用 TypeTag

import reflect.runtime.universe._

class Observable[Foo]

def X[T: TypeTag](ob: Observable[T]) = ob match 
    case x if typeOf[T] <:< typeOf[Double]   => println("Double obs")
    case x if typeOf[T] <:< typeOf[Boolean]  => println("Boolean obs")
    case x if typeOf[T] <:< typeOf[Int]      => println("Int obs")


X(new Observable[Int])
// Int obs

另见this lengthy, but awesome answer

还请注意,我只是瞥见了 scala 反射,因此很可能有人会写一个更好的 TypeTag 用法示例。

【讨论】:

需要注意的是,ob 上的模式匹配在这种情况下是多余的,因为它完全基于 if-else 逻辑,x 不会改变类型。 所以没有compile-time 的方式来匹配T 的类型?换句话说,这个答案是the 答案——没有别的办法吗? @KevinMeredith 我想是的。有一篇“在 Scala 中模式匹配泛型类型的方法”博客文章提供了更多见解和替代方法:cakesolutions.net/teamblogs/… 现在可以在这里找到“在 Scala 中模式匹配泛型类型的方法”博文:lepovirta.org/posts/… 或 gist.github.com/jkpl/5279ee05cca8cc1ec452fc26ace5b68b

以上是关于Scala中泛型类型的模式匹配的主要内容,如果未能解决你的问题,请参考以下文章

Scala基础 模式匹配样例类与Actor编程

Scala基础 模式匹配样例类与Actor编程

Scala:基础知识03

Scala:样例类模式匹配Option偏函数泛型

Scala中泛型类型之间的比较

scala 常用模式匹配类型