重新分配给 Scala 中的 val

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3908806/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 02:29:49  来源:igfitidea点击:

Reassignment to a val in Scala

scalascala-collections

提问by Mansur Ashraf

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

我正在 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)
  }

}

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)

回答by Ken Bloom

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

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

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

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

回答by Aaron Novstrup

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

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

回答by missingfaktor

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

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

回答by Kevin Wright

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

如前所述,错误消息源自表达式 ...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 toMapmethod.

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

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
    )
  }
}