2015-09-22 5 views
0

Я бегу с Groovy «рекурсивно» на карту и пытаюсь изменить все значения, которые BigDecimal набрал Double, используя Tail-recursion, чтобы избежать StackOverFlow.Зачем мне нужно явно использовать метод Groovy trampoline.call() для рекурсии?

Я уже сделал это, создав метод, используя аннотацию @TailRecursive. Теперь я пытаюсь с простым закрытием и батут, как это:

def mapToTest = [ 
    key1: "String1", 
    key2: new BigDecimal(2), 
    key3: "String3", 
    key4: [attr1:'attrValue1', attr2: new BigDecimal(4)], 
    key5:new BigDecimal(5) 
] 

def deepDoubler 
deepDoubler = { Map map, boolean rec -> 
    println "is rec? ${rec}" 
    map.each { k, v -> 
     println (v instanceof Map) 
     if (v instanceof Map){ 
      println "calling recursively... ${v}" 
      deepDoubler.trampoline(v, true) 
     } else if (v instanceof BigDecimal) { 
      map[k] = new Double(0) 
     } 
    } 
}.trampoline() 
deepDoubler(mapToTest, false) 

Я добавил булево значение только для печати и на самом деле я могу напечатать «вызов рекурсивно», но метод никогда не выполняется, если я не добавить метод call() после инструкции на батуте.

if (v instanceof Map){ 
println "calling recursively... ${v}" 
deepDoubler.trampoline(v, true).call() // call() here otherwise it doesn't run 

Кто-нибудь знает, почему он работает, когда я выполняю метод call()? Я пробовал много примеров API, и они хорошо работают без явного вызова(), но я не нашел никакого примера с Map.

Спасибо!

ответ

0

trampoline метод не вызывает закрытие, но украшает его и возвращает модифицированное закрытие - см. here. Вы должны называть украшенное закрытие явно через () или call().

+0

Спасибо за ваш ответ! Взяв пример [link] (https://wakeupcode.wordpress.com/2015/08/18/groovy-functional-sugar-trampoline/), почему здесь нет явного вызова()? –

+0

В этой строке: 'assert sizeList (1..10000) == 10000', именно здесь' (1..10000) ':) – Opal

+0

@CassioDC, если мой ответ решает проблему, пожалуйста, примите его. – Opal

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