Scala反射:我可以查看某物是否为(案例)对象吗?

时间:2018-11-23 12:57:41

标签: scala reflection

Scala中有没有办法查看是否将类定义为对象?

def isObject(c: Class[_]): Boolean = ???

object X
class Y

val x = X
val y = new Y

isObject(x.getClass) == true
isObject(y.getClass) == false

2 个答案:

答案 0 :(得分:4)

使用scala-reflect,以下方法似乎有效:

object ObjectReflection extends App {

  import scala.reflect.runtime.universe._

  def isObject[T](x: T)(implicit tag: TypeTag[T]): Boolean = PartialFunction.cond(tag.tpe) {
    case SingleType(_, _) => true
  }

  object AnObject
  case object ACaseObject
  class AClass
  case class ACaseClass(i: Int)
  trait ATrait

  println("new AClass     " +  isObject(new AClass))
  println("ACaseClass(42) " +  isObject(ACaseClass(42)))
  println("new ATrait {}  " +  isObject(new ATrait {}))
  println("AnObject       " +  isObject(AnObject))
  println("ACaseObject    " +  isObject(ACaseObject))

}

打印:

new AClass     false
ACaseClass(42) false
new ATrait {}  false
AnObject       true
ACaseObject    true

取决于:

libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value

答案 1 :(得分:1)

首先,您可以

newCols <- do.call(rbind, Map(function(u, v, x, y) {
     u1 <- as.numeric(u)
     v1 <- as.numeric(v)
     v2 <- as.numeric(v1[u1 >x & u1 < y])
     i1 <- with(rle(v2 > 0), pmax(max(lengths[values]), 0))
     i2 <- sum(v2 > 0)
     lb <- match(x, u1)
     ub <- match(y, u1)
     v3 <- as.numeric(v[(lb+1):(ub-1)])

     i3 = with(rle(v3 > min(as.numeric(v[c(lb, ub)]))), 
                      pmax(max(lengths[values]), 0))
      data.frame(First = i1, Second = i2, Third = i3)
      },
         strsplit(DT$Time, ","), strsplit(DT$Intensity, ","), DT$Low, DT$High))

cbind(DT, newCols)
#  A  B Low High                   Time                                        Intensity First Second Third
#1: aa  H   0    8 0,1,2,3,4,5,6,7,8,9,10                       0,0,0,0,561464,0,0,0,0,0,0     1      1     1
#2: aa  H   3   10 0,1,2,3,4,5,6,7,8,9,10               0,0,0,6548,5464,5616,0,0,0,68716,0     2      3     2
#3: bb Na   1    9 0,1,2,3,4,5,6,7,8,9,10 5658,12,6548,6541,8,5646854,54565,56465,546,65,0     7      7     4
#4: bb Na   1    8 0,1,2,3,4,5,6,7,8,9,10                       0,561464,0,0,0,0,0,0,0,0,0     0      0     0

因为为单例def isObject(c: Class[_]): Boolean = c.getName.endsWith("$") 创建的匿名类的名称为object y,而通常的匿名类(例如y$)则以new AnyRef {}结尾。

但是也创建$<number>是合法的,这会产生误报;这样的名字实际上很少见。

使用scala-reflect应该可以给出更精确的答案。