【问题标题】:Function that checks if arg1 is an instance of arg2, like isInstanceOf(a,A) in Scala检查 arg1 是否为 arg2 实例的函数,例如 Scala 中的 isInstanceOf(a,A)
【发布时间】:2014-12-02 22:49:07
【问题描述】:

我一直在尝试想出一个函数来检查参数是否属于运行时给定的类型。

考虑以下示例中的函数is(“is of class”的缩写):

    object TestClass {
        abstract class P()
        case class A() extends P
        case class B() extends P
        // ...
        case class Z() extends P

        def is[VALUE,TYPE](value:VALUE, T:TYPE): Boolean = {
            value match {
                case T => true
                case _ => false
            }
        }

        def main(args: Array[String]) {
            val a = new A()
            val b = new B()

            println(a.isInstanceOf[A]) // true
            println(is(a, A)) // false
            println(is(b, B)) // false
        }
    }

我已经阅读过有关 ClassTag 和 getClass 的信息,但我是 Scala 新手,似乎无法正确应用它们。应该如何为所有println-行实现is以返回true

【问题讨论】:

    标签: class scala reflection


    【解决方案1】:

    您正在检查 T,这将是 AB伴随对象 - 它可能更容易理解是什么如果您使用非案例类,则继续。

    更正代码后,您会发现它始终返回 true,并警告该模式由于擦除而未检查:

    def is[TYPE](value: Any): Boolean = value match {
      case t: TYPE => true
      case _ => false
    }
    

    解决这个问题的常用方法是使用ClassTag 作为模式:

    def is[TYPE](value: Any)(implicit tag: ClassTag[TYPE]): Boolean = value match {
      case tag(_) => true
      case _ => false
    }
    

    请注意,这只会匹配运行时、已擦除的类,因此对于泛型类型,您会得到令人惊讶的答案:

    is[List[Int]](List("abc")) //true
    

    如果您想要更通用的解决方案,您可能需要查看Shapeless type-safe extractors

    【讨论】:

      猜你喜欢
      • 2014-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多