为什么可变和不可变集中的类型推断的行为如此不同?

存在

运行以下代码时,我得到了一些奇怪的结果:

object Example {

  implicit object StringOrdering extends Ordering[String] {
    def compare(o1: String, o2: String) = {
      o1.length - o2.length
    }
  }
  object StringOrdering1 extends Ordering[String] {
    def compare(o1: String, o2: String) = {
      o2.length - o1.length
    }
  }


  import collection.mutable
  import collection.immutable.TreeSet

  val x = TreeSet(1, 5, 8, 12)
  val y = mutable.Set.empty ++= x // mutable.Set[Int]
  val y1 = mutable.Set.empty[Int] ++= x // mutable.Set[Int]
  val z = TreeSet.empty ++ y // Set[Any]
  val z1 = TreeSet.empty[Int] ++ y // TreeSet[Int]
}

为什么可变和不可变集中的类型推断的行为如此不同?z部分最令人困惑,为什么我们至少没有得到一个TreeSet[Any]

迈克尔·扎亚克(Michael Zajac)

该问题可以简化为以下形式:

scala> TreeSet.empty[Int] ++ TreeSet.empty[BigInt]
res15: scala.collection.immutable.Set[Any] = Set()

您对的使用TreeSet.empty不会显示其实际类型。实际上,它甚至不能按原样编译。我正在假设Ordering[A]您在未显示的范围内有一些隐含的地方where A != Int

关于这个问题:

为什么我们至少没有得到TreeSet [Any]

简单的答案是,你不能有一个TreeSet[Any]没有Ordering[Any]如果我尝试将aTreeSet[Int]与a结合使用TreeSet[BigInt],则它们最常见的类型是AnyATreeSet是的一种SortedSet,但是我们如何排序一组Any呢?默认情况下,我们不能这样做,因为对一组进行排序实际上没有任何意义Any

Ordering[Any]如果我真的想要话,我可以设计一个,最后我会得到一个TreeSet[Any]

implicit val ordAny = new Ordering[Any] {
    def compare(x: Any, y: Any): Int = Ordering.Int.compare(x.hashCode, y.hashCode)
}

scala> TreeSet.empty[Int] ++ TreeSet.empty[BigInt]
res8: scala.collection.immutable.TreeSet[Any] = TreeSet()

但这并没有任何意义。

技术上的答案是,为了连接两个TreeSetTreeSet[A]并且TreeSet[B],我们需要一个隐式CanBuildFrom[TreeSet[A], B, TreeSet[B]]

一些 CanBuildFromS按产生的SortedSetFactory,但通知他们如何需要一个隐式Ordering[A]由于Ordering[Any]找不到,因此编译器会寻找更通用的东西,并找到Set[Any]这是有道理的,因为如果我们将元素放入不知道如何排序的排序集中,那么我们将不再具有排序集。剩下的只是一个平原Set

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么指向静态不可变变量的不可变指针不同步?

来自分类Dev

为什么不可变映射和记录的属性访问器方法不同?

来自分类Dev

为什么SharedArray的SetIndex抱怨不可变类型?

来自分类Dev

为什么Java的类型推断如此弱?

来自分类Dev

不可变的 null 和默认行为

来自分类Dev

Scala:为什么可变Map和不可变Map在作为键的同一个自定义类实例上有不同的结果?

来自分类Dev

没有重复的C#不可变和可变类型

来自分类Dev

为什么不可变对象的属性在Swift中是可变的?

来自分类Dev

为什么不可变编程比可变编程更受欢迎?

来自分类Dev

自动属性和不可变类型

来自分类Dev

自动属性和不可变类型

来自分类Dev

为什么LinkedListNode类是不可变的?

来自分类Dev

为什么IEnumerable投影不是不可变的?

来自分类Dev

为什么Java Optionals是不可变的?

来自分类Dev

为什么数组的长度是不可变的?

来自分类Dev

为什么Elasticsearch中的文档是不可变的?

来自分类Dev

为什么整数在Python中是不可变的?

来自分类Dev

为什么iter()借用列表是不可变的?

来自分类Dev

为什么lucene的片段是不可变的

来自分类Dev

为什么字典键必须是不可变的?

来自分类Dev

为什么iter()借用列表是不可变的?

来自分类Dev

为什么不鼓励不可变 null?

来自分类Dev

为什么Rust无法在类型构造函数中将可变引用强制转换为不可变引用?

来自分类Dev

为什么只有字符串是不可变的而不是其他数据类型

来自分类Dev

Redux和不可变

来自分类Dev

Redux和不可变

来自分类Dev

Julia函数:使可变类型不可变

来自分类Dev

为什么JavaScript Primitive-Variables不可变而Object-Variables不可变?

来自分类Dev

无法将不可变值作为inout参数传递:文字不可变,为什么?

Related 相关文章

  1. 1

    为什么指向静态不可变变量的不可变指针不同步?

  2. 2

    为什么不可变映射和记录的属性访问器方法不同?

  3. 3

    为什么SharedArray的SetIndex抱怨不可变类型?

  4. 4

    为什么Java的类型推断如此弱?

  5. 5

    不可变的 null 和默认行为

  6. 6

    Scala:为什么可变Map和不可变Map在作为键的同一个自定义类实例上有不同的结果?

  7. 7

    没有重复的C#不可变和可变类型

  8. 8

    为什么不可变对象的属性在Swift中是可变的?

  9. 9

    为什么不可变编程比可变编程更受欢迎?

  10. 10

    自动属性和不可变类型

  11. 11

    自动属性和不可变类型

  12. 12

    为什么LinkedListNode类是不可变的?

  13. 13

    为什么IEnumerable投影不是不可变的?

  14. 14

    为什么Java Optionals是不可变的?

  15. 15

    为什么数组的长度是不可变的?

  16. 16

    为什么Elasticsearch中的文档是不可变的?

  17. 17

    为什么整数在Python中是不可变的?

  18. 18

    为什么iter()借用列表是不可变的?

  19. 19

    为什么lucene的片段是不可变的

  20. 20

    为什么字典键必须是不可变的?

  21. 21

    为什么iter()借用列表是不可变的?

  22. 22

    为什么不鼓励不可变 null?

  23. 23

    为什么Rust无法在类型构造函数中将可变引用强制转换为不可变引用?

  24. 24

    为什么只有字符串是不可变的而不是其他数据类型

  25. 25

    Redux和不可变

  26. 26

    Redux和不可变

  27. 27

    Julia函数:使可变类型不可变

  28. 28

    为什么JavaScript Primitive-Variables不可变而Object-Variables不可变?

  29. 29

    无法将不可变值作为inout参数传递:文字不可变,为什么?

热门标签

归档