【问题标题】:scala: compare types of inner class objectsscala:比较内部类对象的类型
【发布时间】:2015-03-19 05:16:19
【问题描述】:

我如何知道内部类的两个对象是否具有相同的运行时类型? 在下面的示例中,我希望看到 aa.getClass == a.Inner 和 ba.getClass == b.Inner 的类,但实际上它们都是 Outer.Inner 和相等的。

class Outer{
      class Inner{}
    }

    val a = new Outer
    val b = new Outer

    val aa = new a.Inner
    val ab = new a.Inner
    val ba = new b.Inner

    val res1 = aa.getClass == ba.getClass
    val res2 = aa.isInstanceOf[ab.type ]

    scala>      |      | defined class Outer

    scala> a: Outer = Outer@550a1967

    scala> b: Outer = Outer@5f9678e1

    scala> aa: a.Inner = Outer$Inner@70a36a66

    scala> ab: a.Inner = Outer$Inner@1dd6d4b7

    scala> ba: b.Inner = Outer$Inner@2e61d218

    scala> res1: Boolean = true

    scala> res2: Boolean = false

【问题讨论】:

    标签: scala


    【解决方案1】:

    ... aa.getClass == a.Inner 和 ba.getClass == b.Inner,但实际上它们都是 Outer.Inner 和相等的

    这不是真的。 Inner 是一个类成员,对于 Outer 的父实例是唯一的。这意味着ab 都有自己独特的Inner 版本,它们是不兼容的类型。所以a.Innerb.Inner 的类型不同,因此a.Inner 永远不能等于b.Inner。我不能为另一个分配一个:

    scala> val z: a.Inner = aa       // aa is a.Inner, so this is ok
    z: a.Inner = Outer$Inner@575d06dd
    
    scala> val z: b.Inner = aa       // aa is not b.Inner, so it fails to compile
    <console>:14: error: type mismatch;
     found   : a.Inner
     required: b.Inner
           val z: b.Inner = aa
                            ^
    

    getClass 在这里用处不大。

    我们可以通过反射来证明这一点:

    import scala.reflect.runtime.universe._
    
    def tpeOf[A](a: A)(implicit tt: TypeTag[A]) = tt.tpe
    
    scala> tpeOf(aa) =:= tpeOf(ba) // different Outer parents
    res24: Boolean = false
    
    scala> tpeOf(aa) =:= tpeOf(aa) // Same instance
    res25: Boolean = true
    
    scala> tpeOf(aa) =:= tpeOf(ab) // Same Outer parent
    res26: Boolean = true
    

    另一方面,您可以使用Outer#Inner 指定您不关心您的Inner 类型属于哪个Outer

    val x: Outer#Inner = aa
    val x: Outer#Inner = ab
    val x: Outer#Inner = ba
    

    正如@BenReich 所说,您可以使用aa.isInstanceOf[Outer#Inner] 来检查您是否有任何这些类型,它们都会返回true

    ab.type 意味着完全不同的东西。 ab.type 是一个只包含 ab 的单例类型。那么很自然,aa.isInstanceOf[ab.type] 一定是假的,因为aa 不是ab,不管它们是否都是a.Inner

    【讨论】:

    • 可能值得一提的是,它们都可以分配给Outer#Inner
    • 谢谢!奇怪的是我们需要编写一个自定义方法来比较内部类对象时使用...
    • @Yegor 请注意,您可以执行ab.isInstanceOf[Outer#Inner] 以获得所需的效果。
    • @Yegor 我的自定义方法更多是为了弥补我对反射库知识的不足。可能有一种方法已经做到了,但我只是想要一种快速的方法来使用我已经知道的TypeTags 来比较类型
    猜你喜欢
    • 2012-11-16
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    • 2017-05-15
    相关资源
    最近更新 更多