2013-06-26 5 views
3

Я не могу понять, как я могу сделать следующий код незыблемым:Делать мир кода неизменного

def function123(str: String, mapVal: Map[String, String]) = { 
    var str1 = str 
    mapVal.keySet.foreach({x => 
     str1 = str1.replaceAll(/*some pattern involving x*/, mapVal.get(x).get)}) 
    str1 
} 

Я подозреваю, что я хотел бы использовать foldLeft или вложенный метод с параметром-аккумулятором, но это только мои мысли.

Итак, как мне это сделать?

+1

Обычно вы делаете объекты неизменными, из ваших двух параметров строка уже неизменна и Map, вы можете копировать и возвращать новую карту каждый раз. – Sap

ответ

5

foldLeft

У вас есть цикл здесь.

Неизменной версия петли с побочными эффектами является foldLeft со всеми побочными эффектами заменены следующим состоянием созданием:

val result = mapVal.foldLeft(str){case (state, (key, value)) => 
    state.replaceAll(/*some pattern involving key*/, value) 
} 

Для работы в непреложной среде каждой итерация цикла должна возвращать значение и принимать результат предыдущих итерация как параметр. Это именно то, что foldLeft.

рекурсии

Другим решением является рекурсивным методом. Вы должны извлечь итерации цикла к методу и сделать этот метод для вызова следующей итерации в конце:

def function123(str: String, mapVal: Map[String, String]) = { 
    @tailrec def loop(state: String, pairs: List[(String, String)]): String = pairs match { 
    case Nil => state 
    case (key, value) :: tail => 
     val nextState = state.replaceAll(/*some pattern involving key*/, value) 
     loop(nextState, tail) 
    } 
    loop(str, mapVal.toList) 
} 

Мутабельном петля -> неизменны

Для кода с изменяемым контуром неизменяемыми вы должны извлечь все значения, неявно участвующие в изменениях в цикле, в какое-то состояние (единый государственный объект для foldLeft или набор параметров для рекурсивного метода), а затем создают новое состояние, основанное на предыдущем в конце каждой итерации.

+0

«Неизменяемая версия петли с побочными эффектами - foldLeft со всеми побочными эффектами, заключенными в состояние '- какие побочные эффекты вы имеете в виду? –

+0

@MariusKavansky: Посмотрите последнее обновление. Я имею в виду все побочные эффекты. Все действия, которые требуют переназначения любой ценности. Любые переназначения 'var' или мутаций изменяемых объектов. Обратите внимание, что 'I/O' и отправка сообщений - это операции с побочными эффектами. – senia

+0

извините, пока неясно. в вашем первом примере нет «var» и, таким образом, никаких побочных эффектов. где они? –

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