【问题标题】:Difference between Object and AnyRef in ScalaScala中Object和AnyRef之间的区别
【发布时间】:2019-04-25 09:20:30
【问题描述】:

this scheme 在 Scala 之旅中的 Unified typed 文章中,我认为 AnyRefObject 是完全等价的。

但是,在 Eclipse 中检查声明时,我发现了一些有趣的事情:

object ClassTag {
  …
  val Object  : ClassTag[java.lang.Object] = Manifest.Object
  …
  val AnyRef  : ClassTag[scala.AnyRef]     = Manifest.AnyRef
  …
}

object TypeTag {
  …
  val AnyRef:  TypeTag[scala.AnyRef]     = new PredefTypeTag[scala.AnyRef]     (AnyRefTpe,  _.TypeTag.AnyRef)
  val Object:  TypeTag[java.lang.Object] = new PredefTypeTag[java.lang.Object] (ObjectTpe,  _.TypeTag.Object)
  …
}

一些实验:

import scala.reflect.ClassTag
import scala.reflect.runtime.universe.TypeTag

println(ClassTag.AnyRef == ClassTag.Object) //true
def getClassTag[V](v: V)(implicit tag: ClassTag[V]) = tag
println(getClassTag[AnyRef](null)) //Object
println(getClassTag[Object](null)) //Object
println(getClassTag(null.asInstanceOf[AnyRef])) //Object
println(getClassTag(null.asInstanceOf[Object])) //Object
println(getClassTag(new AnyRef())) //Object
println(getClassTag(new Object())) //Object
println
println(TypeTag.AnyRef == TypeTag.Object) //false
def getTypeTag[V](v: V)(implicit tag: TypeTag[V]) = tag
println(getTypeTag[AnyRef](null)) //TypeTag[AnyRef]
println(getTypeTag[Object](null)) //TypeTag[Object]
println(getTypeTag(null.asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(null.asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new AnyRef())) //TypeTag[Object]
println(getTypeTag(new Object())) //TypeTag[Object]
println(getTypeTag(new AnyRef().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new AnyRef().asInstanceOf[Object])) //TypeTag[Object]
println(getTypeTag(new Object().asInstanceOf[AnyRef])) //TypeTag[AnyRef]
println(getTypeTag(new Object().asInstanceOf[Object])) //TypeTag[Object]
println
println(TypeTag.AnyRef.tpe == TypeTag.Object.tpe) //false
def getType[V](v: V)(implicit tag: TypeTag[V]) = tag.tpe
println(getType[AnyRef](null)) //AnyRef
println(getType[Object](null)) //Object
println(getType(null.asInstanceOf[AnyRef])) //AnyRef
println(getType(null.asInstanceOf[Object])) //Object
println(getType(new AnyRef())) //Object
println(getType(new Object())) //Object
println(getType(new AnyRef().asInstanceOf[AnyRef])) //AnyRef
println(getType(new AnyRef().asInstanceOf[Object])) //Object
println(getType(new Object().asInstanceOf[AnyRef])) //AnyRef
println(getType(new Object().asInstanceOf[Object])) //Object

因此,至少在某些级别的类型信息ObjectAnyRef 是有些区别的。它是做什么用的?还是纯粹是个bug?

【问题讨论】:

  • TypeTagClassTag 只是提供两个不同的东西。请参阅stackoverflow.com/questions/40202504/…medium.com/@sinisalouc/… 您可能看到TypeTag AnyRefObject 之间的实际区别,因为TypeTag 处理类型并且AnyRef 确实不同于Object 类型明智的,因为 AnyRef 只是一个 trait 并且确实不同于 AnyRef github.com/scala/scala/tree/2.12.x/src/library-aux/scala
  • 请注意,您不需要getTypeTag,您可以只写例如implicitly[TypeTag[AnyRef]] 召唤一个实例。
  • @DanielHinojosa,有趣的是AnyRef 被声明为特征。但我不认为这真的是一个特征,我认为一些编译器魔法以不同的方式处理标准库中的这些核心内容。首先,我相信Seth Tissue's opinion;第二,我可以new AnyRef(),但不能trait T; new T();第三,typeTag.mirror.runtimeClass(typeTag.tpe).isInterface()AnyRef 返回false(通常它为特征返回true)。
  • @Sasha 这是一个有趣的问题,我认为之前的自述文件会带来一些答案。 github.com/scala/scala/blob/2.12.x/src/library-aux/README。 “此目录下的源文件无法通过正常方式编译。它们存在用于引导和文档目的。”因此,在 scala 引导过程中有些东西会采用 AnyRef 的特性并在运行时(可能)将其与 java.lang.Object 合并,但 TypeTagsAnyRefObject 是不同的。现在,bootstrap 发生了什么?

标签: scala types


【解决方案1】:

你会看到任何类型别名的类似行为,我认为在上面的示例中 Object/AnyRef 没有什么特别之处。

scala 2.12.7> import scala.reflect.runtime.universe.TypeTag
import scala.reflect.runtime.universe.TypeTag

scala 2.12.7> class C; type D = C
defined class C
defined type alias D

scala 2.12.7> implicitly[TypeTag[C]]
res0: reflect.runtime.universe.TypeTag[C] = TypeTag[C]

scala 2.12.7> implicitly[TypeTag[D]]
res1: reflect.runtime.universe.TypeTag[D] = TypeTag[D]

CD 是不同但“等效”的类型。请参阅 SLS 3.5,“类型之间的关系”(https://www.scala-lang.org/files/archive/spec/2.12/03-types.html#relations-between-types)

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 2013-06-16
    • 2010-11-28
    • 2010-11-04
    • 1970-01-01
    • 2011-12-07
    • 2021-02-19
    • 2012-04-04
    相关资源
    最近更新 更多