我是Scala世界的新手,现在我正在阅读名为《 Scala in Action》(由Nilanjan Raychaudhuri撰写)的书,即第97页上的名为“可变对象需要不变”的那部分,而我不理解以下哪部分:直接取自上述书籍。

假设ListBuffer是协变的,并且下面的代码段可以正常工作而没有任何编译问题:

scala> val mxs: ListBuffer[String] = ListBuffer("pants")
mxs: scala.collection.mutable.ListBuffer[String] =
ListBuffer(pants)
scala> val everything: ListBuffer[Any] = mxs
scala> everything += 1
res4: everything.type = ListBuffer(1, pants)

你能发现问题吗?由于所有内容均为“任意”类型,因此您可以存储
将整数值转换为字符串集合。这是一场灾难,等待发生。为避免此类问题,始终
使可变对象不变的好主意。

我将有以下问题。

1)实际上是哪种类型的everythingStringAny?声明是“val everything: ListBuffer[Any]”,因此我期望Any,因为一切都应该是Any的类型,那么我认为在一个Integer中包含StringListBuffer[Any]不会出现任何问题。我如何将整数值存储到字符串集合中,它们如何编写???为什么会灾难???为什么要使用List(不可变)而不是ListBuffer(可变)?我没看出任何区别。我发现了很多答案,可变集合应该具有类型不变,而可变集合应该具有协变量类型,但是为什么呢?

2)最后一部分“res4: everything.type = ListBuffer(1, pants)”是什么意思? “everything.type”是什么意思?我猜everything没有称为type的任何方法/函数或变量。为什么没有ListBuffer [Any]或ListBuffer [String]?

非常感谢,

安德鲁

最佳答案

1 这看起来不是一个单一的问题,所以我必须进一步细分它:

  • “实际上” everythingListBuffer[_],具有擦除的参数类型。根据JVM,它包含对某些对象的32位或64位引用。编译器在编译时就知道ListBuffer[String]ListBuffer[Any]类型。如果它“知道”两个矛盾的事情,那么显然很糟糕。
  • “我看不到将Integer和String包含在内的任何问题
    一个ListBuffer [Any]”。Int中没有StringListBuffer[Any]是没有问题的,因为ListBuffer是不变的。但是,在您的假设示例中,ListBuffer是协变的,因此您将Int存储在ListBuffer[String]中。 Int中的ListBuffer[String],并尝试将其解释为String,那么显然很糟糕。
  • “如何将整数值存储到集合中
    如何写字符串?”如上所述,您为什么要做明显很糟糕的事情?
  • “为什么会发生灾难???”这不会是一场大灾难。 Java一直都在使用协变数组。它不会导致大灾变,只是不好而且令人讨厌。
  • “为什么要使用List(不可变)而不是ListBuffer(可变)?”没有绝对的必要条件告诉您始终使用List而不要使用ListBuffer。适当时请同时使用两者。在99.999%的情况下,List当然更合适,因为与设计需要List局部可变状态的复杂算法相比,使用ListBuffer表示数据的频率更高。
  • “我发现了很多可变的答案
    应该具有不变的类型,并且不可变的集合应该
    具有协变类型,但为什么呢?”。这是错误的,您过于简化了。例如,内涵不可变集既不应协变,也不应不变,而应是互变的。在适当的情况下,应使用协方差,协变和不变性。也许您也觉得它有用。

  • 2 这是This little silly illustration has proven unreasonably effective for explaining the difference,就像下面的示例一样:
    scala> val x = "hello"
    x: String = hello
    
    scala> val y: x.type = x
    y: x.type = hello
    

    这是一个singleton type

    关于scala - Scala-可变集合中的协变类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49410925/

    10-10 14:02