重新分配给 Scala 中的 val

发布于 2024-09-27 15:25:16 字数 1483 浏览 2 评论 0原文

我正在 Scala 中进行训练练习并收到此 val 重新分配错误。我不知道在哪里为 val 重新分配新值

class personTest
{
  val alf = Person("Alf", 30, List(EmailAddress("[email protected]")))
  val fredrik = Person("Fredrik", 33, List(EmailAddress("[email protected]"), EmailAddress("[email protected]")))
  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)

I am doing a training exercise in Scala and getting this val reassignment error. I don't see where I am reassigning a new value to a val

class personTest
{
  val alf = Person("Alf", 30, List(EmailAddress("[email protected]")))
  val fredrik = Person("Fredrik", 33, List(EmailAddress("[email protected]"), EmailAddress("[email protected]")))
  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)
  }

}

and I am getting this error

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

酷遇一生 2024-10-04 15:25:16

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

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

b which is the name of a parameter to your closure is itself a val, which cannot be reassigned.

foldLeft works by taking passing the return value of one invocation of the closure as the parameter b to the next, so all you need to do is return b + (p.name->p.emailAddresses). (Don't forget the parentheses for precedence.)

感悟人生的甜 2024-10-04 15:25:16

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

You're reassigning val b in the expression b+=p.name->p.emailAddresses.

睡美人的小仙女 2024-10-04 15:25:16

不可变的 Map 没有 += 方法。在这种情况下,编译器会翻译 b += p.name -> p.emailAddressesb = b + p.name->p.emailAddresses。好了,重新分配!

Immutable Map does not have a += method. In such case, compiler translates b += p.name -> p.emailAddresses to b = b + p.name->p.emailAddresses. There you have it, reassignment!

浮生面具三千个 2024-10-04 15:25:16

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

但实际上,您根本不需要在这里执行 FoldLeft,这是一个简单的映射应该足够了。然后,任何 Seq[K->V] 都可以通过 toMap 方法转换为 Map[K,V]

像这样的东西:

免责声明:未测试拼写错误等

class personTest {
  val alf = Person(
    "Alf",
    30,
    EmailAddress("[email protected]") ::
    Nil
  )

  val fredrik = Person(
    "Fredrik",
    33,
    EmailAddress("[email protected]") ::
    EmailAddress("[email protected]") ::
    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
    )
  }
}

As previously mentioned, the error message is originating in the expression ...b+=bp.name...

But really, you don't need to be doing a foldLeft here at all, a simple mapping should be enough. Any Seq[K->V] can then be converted to a Map[K,V] via the toMap method.

Something like this:

disclaimer: not tested for typos, etc.

class personTest {
  val alf = Person(
    "Alf",
    30,
    EmailAddress("[email protected]") ::
    Nil
  )

  val fredrik = Person(
    "Fredrik",
    33,
    EmailAddress("[email protected]") ::
    EmailAddress("[email protected]") ::
    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
    )
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文