【问题标题】:Pattern matching and (ereased) generic function type argument模式匹配和(删除的)泛型函数类型参数
【发布时间】:2014-11-30 16:47:54
【问题描述】:

假设我想编写通用函数foo,它将使用模式匹配来检查传递的参数是否属于其通用参数T的类型

天真的尝试:

  def foo[T]: PartialFunction[Any, Boolean] = {
    case x: T =>
      true
    case _ =>
      false
  }

...自从T 被删除后将无法工作。编译器警告确认:

Warning:(11, 13) abstract type pattern T is unchecked since it is eliminated by erasure
    case x: T =>
            ^

让它发挥作用的最佳方法是什么?

【问题讨论】:

  • 请注意,类型匹配与函数式编程几乎没有关系,它在 Scala 中被破坏的事实实际上是一件好事(遗憾的是它得到部分支持并且该语言提供了解决方法比如ClassTag)。
  • @Travis:Eugeny 的问题没有被标记为“函数式编程”,他也没有提到它。 Scala 不仅是一种函数式编程语言,而且还是一种面向对象(甚至是命令式)的编程语言,那么它为什么不提供一种解决方法呢?匹配类型在面向对象编程中非常有用。如果你不想要面向对象,那么 scala 毕竟是错误的语言。
  • @Martin 我的抱怨与其说是功能,不如说是 Scala 将其与模式匹配混为一谈(这可能是许多人第一次接触 FP)。如果它有自己独特的语法(并且在泛型上没有被严重破坏),那当然很棒。

标签: scala generics pattern-matching type-erasure


【解决方案1】:

Scala 为此引入了ClassTags。它们可以通过隐式参数获取,并且会自动提供,这意味着调用方法时不必担心参数:

import scala.reflect.ClassTag

def foo[T](implicit tag: ClassTag[T]): PartialFunction[Any, Boolean] = {
  case x: T =>
    true
  case _ =>
    false
}

val isString = foo[String] // ClassTag gets provided implicitly here

isString("Hallo") // will return true
isString(42) // will return false

更多解释见docs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多