Clojure:以不同的方式重现匿名函数

时间:2018-12-19 09:06:58

标签: clojure arity

Clojure recur with multi-arity类似,我想使用其他工具重复出现。但就我而言,我想通过let定义函数,因为我想使用let(file-list)中的另一个值而不传递它:

(let [file-list (drive/list-files! google-drive-credentials google-drive-folder-id)
      download-file (fn
                      ([name]
                       (download-file ; <-- attempt to recur
                         name
                         (fn []
                           (throw
                             (ex-info
                               (str name " not found on Google Drive"))))))
                      ([name not-found-fn]
                       (if-let [file (->> file-list
                                          (filter #(= (:original-filename %)
                                                      name))
                                          first)]
                         (drive/download-file! google-drive-credentials file)
                         (not-found-fn))))]
  ;; #
  )

我收到此错误:Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: download-file in this context

2 个答案:

答案 0 :(得分:3)

您可以为fn指定本地名称:

(let [download-file (fn download-file
                      ([name] (download-file name (fn ...))))

您还可以使用letfn

(letfn [(download-file
          ([name] (download-file name (fn ...)))
          ([name not-found-fn] ...)])

答案 1 :(得分:0)

为了使异常错误消息更具可读性,我经常在内部函数名称后附加-fn,如下所示:

(let [download-file (fn download-file-fn [name] ...) ]
   <use download-file> ...)