就像@NathanDavis 所说,let 允许您命名中间值:
(loop [k from res '()]
(if (< (count res) n)
(let [next-k (next-num k)]
(recur next-k (conj res next-k)))
(sort res)))
但是,在获得loop 之前,值得看看您是否可以将核心功能组合成相同的效果。通常,您可以编写一些不太复杂的东西并公开重要的细节。
代码的核心是建立一系列next-num 的重复应用程序。幸运的是,有一个核心函数可以做到这一点:iterate。使用iterate,我们可以创建一个无限的惰性值序列:
(iterate next-num from)
; => (from, from', from'', ...)
但是,我们不想要这些值中的第一个。我们可以通过rest 获得序列的其余部分:
(rest
(iterate next-num from))
; => (from', from'', from''', ...)
此时,我们可以用take获取n的值:
(take n
(rest
(iterate next-num from)))
; => (from', from'', from''')
最后,我们可以对这些n 值进行排序:
(sort
(take n
(rest
(iterate next-num from))))
; => (from'', from', from''')
当然,深度嵌套的函数调用很快就会变得尴尬。线程宏->>(就像它的兄弟->)是一种语法糖,可以让我们将代码重新排列成更好的东西:
(->>
(iterate next-num from)
rest
(take n)
sort)
因此,您可以看到强大的序列操作函数库如何让我们摆脱低级循环。