【问题标题】:Compare types in Scala比较 Scala 中的类型
【发布时间】:2012-10-03 23:15:42
【问题描述】:

我有两个对象,每个对象都有本地定义的类型,我想确定类型是否相同。例如,我想编译这段代码:

trait Bar {
  type MyType
}

object Bar {
  def compareTypes(left: Bar, right: Bar): Boolean = (left.MyType == right.MyType)
}

但是,编译失败并显示“值 MyType 不是 Bar 的成员”。

发生了什么事?有没有办法做到这一点?

【问题讨论】:

    标签: scala


    【解决方案1】:

    您可以这样做,但需要一些额外的机器:

    trait Bar {
      type MyType
    }
    
    object Bar {
      def compareTypes[L <: Bar, R <: Bar](left: L, right: R)(
        implicit ev: L#MyType =:= R#MyType = null
      ) = ev != null
    }
    

    现在,如果我们有以下内容:

    val intBar1 = new Bar { type MyType = Int }
    val intBar2 = new Bar { type MyType = Int }
    val strBar1 = new Bar { type MyType = String }
    

    它按预期工作:

    scala> Bar.compareTypes(intBar1, strBar1)
    res0: Boolean = false
    
    scala> Bar.compareTypes(intBar1, intBar2)
    res1: Boolean = true
    

    诀窍是要求提供 L#MyTypeR#MyType 相同的隐含证据,如果它们不同,则提供默认值 (null)。然后你可以检查你是否得到了默认值。

    【讨论】:

    • 如果忽略默认值 null,这将是一个完整的编译时检查,在这种情况下我更喜欢这样做,因为所有类型在编译时都是已知的。
    • @sschaef,我认为并非所有类型在编译时都是已知的。例如,在以下 bar.MyType 直到运行时才确定:“val bar: Bar = if (/* flip coin */) intBar1 else strBar1”
    • 在运行时不再有抽象类型。因此,隐式参数列表在编译时填充,与您的示例进行比较将始终返回 false。
    猜你喜欢
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    相关资源
    最近更新 更多