Kotlin getOrPut奇怪

时间:2018-03-27 21:47:41

标签: kotlin

以下函数(f1)按预期计算Fibonacci数:

fun f1(n: Int, map: MutableMap<Int, Int> = mutableMapOf(Pair(0, 0), Pair(1, 1))): Int =
        map.getOrPut(n) {
            val a = map.getOrPut(n - 1) { f1(n - 1, map) }
            val b = map.getOrPut(n - 2) { f1(n - 2, map) }
            a + b
        }

但是此版本f2仅返回0,1值:

fun f2(n: Int, map: MutableMap<Int, Int> = mutableMapOf(Pair(0, 0), Pair(1, 1))): Int =
        map.getOrPut(n) {
                    map.getOrPut(n - 1) { f2(n - 1, map) }
                    +
                    map.getOrPut(n - 2) { f2(n - 2, map) }

        }

看起来f2只占用第一个“分支”:map.getOrPut(n - 1) { f2(n - 1, map) }而不是第二个。 我知道f2可以像这样修复:

fun f2(n: Int, map: MutableMap<Int, Int> = mutableMapOf(Pair(0, 0), Pair(1, 1))): Int =
        map.getOrPut(n) {
            (
                    map.getOrPut(n - 1) { f2(n - 1, map) }
                    +
                    map.getOrPut(n - 2) { f2(n - 2, map) }
            )
        }

为什么需要(..)

修改

正如@ user2357112和@emerssso所解释的那样,这是一个错误推断的分号的情况,以下是按预期工作的

fun f2(n: Int, map: MutableMap<Int, Int> = mutableMapOf(Pair(0, 0), Pair(1, 1))): Int =
        map.getOrPut(n) {
                    map.getOrPut(n - 1) { f2(n - 1, map) } +
                    map.getOrPut(n - 2) { f2(n - 2, map) }
        }

不酷。

1 个答案:

答案 0 :(得分:4)

这是因为Kotlin在+之后插入一个分号,并将+映射到the unary plus operator,而不是您直观期望的正常双参数加运算符。

您可以通过执行转到声明(命令+单击Mac)来确认这一点,并将其结构化为您的问题。它需要我一元加上你的格式,正常加上加括号或没有换行。

这个意外的分号的结果是它将递归Fibonnacci生成,但从不做任何添加,默默地总是只返回getOrPut(n-2)步的结果(因为它是函数中的最后一个语句)。