重新分配给 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
Reassignment to a val in Scala
提问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.emailAddresses为b = 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
)
}
}

