【问题标题】:Scala Seq[Seq[SomeClass]] type mismatch for mutable collectionScala Seq[Seq[SomeClass]] 可变集合的类型不匹配
【发布时间】:2018-08-22 19:04:11
【问题描述】:

我遇到了与多个 Seq 嵌套和可变集合相关的问题。如果我使用 Seq[Seq[SomeClass]] 并为 Seq 使用可变集合,它将在 IntelliJ 中产生类型不匹配为Type mismatch, expected: String, actual: SomeClass。如果我运行它,它会抛出

value += 不是 Seq[SomeClass] 的成员。表达式不会转换为赋值,因为接收者不可赋值。

代码如下。错误在k1Class.students += mary,代码中有注释。

package core

import scala.collection.mutable
import scala.collection.mutable.{ArrayBuffer, ListBuffer}

case class Student(age: Int, name: String)
case class Class(topic: String, students: Seq[Student])

object Test2 {

  def main(args: Array[String]): Unit = {
    val grades = mutable.HashMap[String, Seq[Class]]()
    val classes = ListBuffer[Class]()
    val students = ArrayBuffer[Student]()

    val bob = Student(7, "Black")

    students += bob

    val musicClass = Class("music", students)

    classes += musicClass

    grades += ("k1" -> classes)

    val k1Classes = grades.get("k1").get

    for (k1Class <- k1Classes){
      val mary = Student(7, "Brown")
      //!!! Error here!!! Type mismatch, expected: String, actual: Student
      k1Class.students += mary  
    }
  }
 }

我很迷茫为什么会这样。非常感谢!

【问题讨论】:

    标签: scala collections


    【解决方案1】:

    我通过两个小改动让它编译。

    import scala.collection.mutable.{ArrayBuffer, ListBuffer, Seq}
                                                              ^^^
    

      k1Class.students.update(0, mary)
    

    通常不鼓励如此严重依赖可变性,但我们都必须从某个地方开始。

    【讨论】:

    • 也最好使用import scala.mutable,然后使用mutable.Seq,因此在代码中很清楚您使用的是可变版本而不是默认的不可变版本。
    • 非常感谢。有效。为什么我不能在这里使用 k1Class.students += mary 的任何原因?此外,在不使用太多可变性的情况下,处理集合不断变化的情况的更好方法是什么?
    • Scaladocs page 可以看出,mutable.Seq 上根本没有+= 方法。为什么不?很难说。也许标准库的作者只是错过了它。至于不可变,您必须开始将带有新元素的List 视为不同的列表,而不是带有新内容的旧列表。这需要一些时间来适应,但它是函数式编程的一个重要方面。
    【解决方案2】:

    如果我使用 Seq[Seq[SomeClass]] 并为 Seq 使用可变集合

    这里重要的是静态类型。 k1Class.students的类型是Seq[Student],这是默认导入的Seqscala.Predef.Seqscala.collection.Seq的别名。所以它不是可变的,也没有定义+=

    【讨论】:

    • 有道理。但令我困惑的是它为什么适用于:' val grades = mutable.HashMap[String, Seq[Class]]() val classes = ListBuffer[Class]() val musicClass = Class("music", students) classes + = musicClass Grades += ("k1" -> classes)' 这里的classes被定义为scala.collection.Seq,然后后者被实现为ListBuffer,应该是mutable.Seq。但是编译器并没有在这里抱怨。这是为什么呢?
    • "这里的类被定义为 scala.collection.Seq"。不,不是。从初始化程序推断它是ListBuffer[Class]。要按照你说的定义它,你需要写val classes: Seq[Class] = ListBuffer[Class](),你会看到编译再次失败。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 2017-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 2014-07-19
    相关资源
    最近更新 更多