8

我正在 Scala 中进行培训练习并遇到此 val 重新分配错误。我看不到在哪里将新值重新分配给 val

class personTest
{
  val alf = Person("Alf", 30, List(EmailAddress("alf.kristian@gmail.com")))
  val fredrik = Person("Fredrik", 33, List(EmailAddress("fredrik@vraalsen.no"), EmailAddress("fvr@knowit.no")))
  val johannes = Person("Johannes", 0, Nil)

  val persons = List(alf, fredrik, johannes)

   @Test
  def testNameToEmailAddress
  {
    // Create a map from each persons name to their e-mail addresses,
    // filtering out persons without e-mail addresses
    // Hint: First filter list, then use foldLeft to accumulate...
    val emptyMap: Map[String, List[EmailAddress]] = Map()

    val nameToEmail = persons.filter(_.emailAddresses.length>0).foldLeft(emptyMap)((b,p)=> b+=p.name->p.emailAddresses)

    assertEquals(Map(alf.name -> alf.emailAddresses, fredrik.name -> fredrik.emailAddresses), nameToEmail)
  }

}

我收到了这个错误

error: reassignment to val
val nameToEmail = persons.filter(_.emailAddresses.length>0).foldLeft(emptyMap)((b,p)=> b+=p.name->p.emailAddresses)
4

4 回答 4

9

b这是闭包的参数名称本身就是 a val,不能重新分配。

foldLeft通过将闭包的一次调用的返回值作为参数b传递给下一次调用,因此您需要做的就是 return b + (p.name->p.emailAddresses)。(不要忘记括号中的优先级。)

于 2010-10-11T18:23:22.583 回答
3

您正在重新分配b表达式中的val b+=p.name->p.emailAddresses

于 2010-10-11T18:13:19.847 回答
3

ImmutableMap没有+=方法。在这种情况下,编译器会转换b += p.name -> p.emailAddressesb = b + p.name->p.emailAddresses. 你有它,重新分配!

于 2010-10-11T18:23:55.077 回答
0

如前所述,错误消息源自表达式...b+=bp.name...

但实际上,您根本不需要在此处进行 foldLeft,一个简单的映射就足够了。Seq[K->V]然后可以Map[K,V]通过该toMap方法 将Any转换为 a。

像这样的东西:

免责声明:未测试错别字等。

class personTest {
  val alf = Person(
    "Alf",
    30,
    EmailAddress("alf.kristian@gmail.com") ::
    Nil
  )

  val fredrik = Person(
    "Fredrik",
    33,
    EmailAddress("fredrik@vraalsen.no") ::
    EmailAddress("fvr@knowit.no") ::
    Nil)

  val johannes = Person(
    "Johannes",
    0,
    Nil)

  val persons = List(alf, fredrik, johannes)

  @Test
  def testNameToEmailAddress {

    val nameToEmailMap =
      persons.view filter (!_.emailAddresses.isEmpty) map {
        p => p.name -> p.emailAddresses
      } toMap

    assertEquals(
      Map(
        alf.name -> alf.emailAddresses,
        fredrik.name -> fredrik.emailAddresses
      ),
      nameToEmailMap
    )
  }
}
于 2010-10-11T18:48:41.643 回答