2010-10-11 2 views
8

Я делаю тренировочное упражнение в Scala и получаю эту ошибку переназначения val. Я не вижу, где я переназначение нового значения к валуПереадресация в val в Scala

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) 

ответ

9

b, который является именем параметра для вашего закрытия, сам по себе является val, который нельзя переназначить.

foldLeft работы, принимая передавая возвращаемое значение одного вызова закрытия в качестве параметра b к следующему, так что все, что вам нужно сделать, это вернуть b + (p.name->p.emailAddresses). (Не забудьте скобки для приоритета.)

+0

Спасибо, что работал тоже, и я не должен использовать изменяемые карту –

3

Вы переназначение Вэл b в выражении b+=p.name->p.emailAddresses.

3

Неизменяемый Map не имеет метода +=. В таком случае компилятор переводит b += p.name -> p.emailAddresses в b = b + p.name->p.emailAddresses. Там у вас есть, переназначение!

+0

Thank You, Я изменил карту на изменчивую карту, и она сработала. Не уверен, что это правильное решение, хотя –

+3

Не нужно использовать изменяемую карту. Вместо этого вы должны изменить '+ =' на '+' (как уже было предложено @Ken Bloom). – missingfaktor

0

Как уже упоминалось ранее, сообщение об ошибке происходящий в выражении ...b+=bp.name...

Но на самом деле, вам не нужно будет делать foldLeft здесь все, простое отображение должно быть достаточно. Любой Seq[K->V] затем может быть преобразован в Map[K,V] с помощью метода toMap.

Что-то вроде этого:

отказ от ответственности: не тестировалось опечаток и т.д.

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

Определение неявного преобразования из 'String' в' EmailAddress' кажется излишним. :) – missingfaktor

+0

Правда, но код был * sooooo * colonplate и широкий, для того, чтобы вписаться в окно StackOverflow. –

+0

Мне нравится цитата из DPP (из его книги): «Я думаю о том, что я думаю о вампирах. очень мощный и очень опасный, и я только приглашаю их в рамки моей программы, когда есть очень веская причина ». –

Смежные вопросы