# 记一次Kotlin tailrec，lambda 作为入参遇到的坑

``````function fact(n) {
if (n == 0) {
return 1;
}

return n * fact(n - 1);
}
``````

CPS 风味:

``````function cps_fact(n, k) {
if (n == 0) {
return k(1);
}

return cps_fact(n - 1, (x) => { return k(x) * n });
}
``````

``````fun cpsFact(a: Int, f: (x: Int) -> Int): Int {
if (a == 0) {
return f(1)
}

return cpsFact(a - 1) { x -> a * f(x) }
}
``````

``````tailrec fun cpsFact(a: Int, f: (x: Int) -> Int): Int {
if (a == 0) {
return f(1)
}

return cpsFact(a - 1) { x -> a * f(x) }
}
``````

``````interface Function {
fun invoke(x: Int): Int
}

tailrec fun cpsFact(a: Int, f: Function): Int {
if (a == 0) {
return f.invoke(1)
}

return cpsFact(a - 1, object : Function {
override fun invoke(x: Int): Int {
return a * f.invoke(x)
}
})
}
``````

Lambda:

``````/** A function that takes 1 argument. */
public interface Function1<in P1, out R> : Function<R> {
/** Invokes the function with the specified argument. */
public operator fun invoke(p1: P1): R
}
``````

``````interface Function {
fun invoke(x: Int): Int

fun invokeWrapper(x: Int): Int
}

tailrec fun cpsFact(a: Int, f: Function): Int {
if (a == 0) {
return f.invokeWrapper(1)
}

return cpsFact(a - 1, object : Function {
override fun invoke(x: Int): Int {
return a * f.invokeWrapper(x)
}

override fun invokeWrapper(x: Int): Int {
return invoke(x)
}
})
}
``````