gpt4 book ai didi

clojure - 为什么我必须在这段代码中使用 (flush) ?

转载 作者:行者123 更新时间:2023-12-02 15:59:18 26 4
gpt4 key购买 nike

这是我第一次接触 Clojure,所以我尝试编写一个简单的脚本,它提供基于维基百科的翻译(欢迎任何批评/评论)

问题是:当我从翻译中删除(刷新)时,脚本输出 nil 而不是翻译后的单词。这是为什么?我显然错过了一些东西,但是什么呢? (println翻译)给出与flush相同的结果(一开始我尝试使用doseq/doall,但没有结果)

(使用 Clojure 1.2 并在 eclipse 3.7.2 中以逆时针方向进行测试)

代码:

(ns wiki-translate
(:require [clojure.contrib.http.agent :as h])
)

(defn get-url
([lg term] (str "http://" lg ".wikipedia.org/wiki/" term))
)

(defn fetch-url
([url] (h/string (h/http-agent url)))
)

(defn get-translations
([cnt] (apply sorted-map (flatten (for [s (re-seq #"(?i)interwiki-([^\"]+).*wiki\/([^\"]+)\".*/a>" cnt)] [(s 1) (s 2)])))))

(defn translate
[term src-lg tgt-lg] (
(def translations (get-translations (fetch-url (get-url src-lg term))) )
(flush)
(if (contains? translations tgt-lg) (get translations tgt-lg) "<NOT FOUND>")
)
)

(println (translate "Shark" "en" "fr"))

最佳答案

translate 函数有一层额外的括号,(flush) 让它意外地工作。没有(flush),代码是

((def translations (get-translations (fetch-url (get-url src-lg term))))
(if (contains? translations tgt-lg) (get translations tgt-lg) "<NOT FOUND>"))

Clojure 根据 its evaluation rules 评估此表单通过评估两个子形式并将第一个子形式作为函数调用。评估子表单后,表单变为

(#'translations
"Requin")

因为第一个形式返回正在定义的 Var,并及时定义它以便第二个形式成功查找。当您将 Var 作为函数调用时,the call is delegated to the value of the Var ,这是一张 map ,并且从 map implements function call as look-up 开始,效果是在 map 中查找“Requin”。 map 上没有带有该键的元素,因此值为 nil。

在其间添加(flush),会发生相同的过程:

((def translations (get-translations (fetch-url (get-url src-lg term))))
(flush)
(if (contains? translations tgt-lg) (get translations tgt-lg) "<NOT FOUND>"))

首先评估为

(#'translations
nil
"Requin")

并且再次调用作为#'translations 值的 map 。这次的效果是查找nil,如果在 map 中找不到nil,则返回“Requin”作为默认值。

关于clojure - 为什么我必须在这段代码中使用 (flush) ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9756019/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com