2024 年 Clojure 状况调查! 中分享您的想法。

欢迎!请参阅 关于 页面以了解更多关于这个工作的信息。

0 投票
命名空间和变量

我刚开始使用 Clojure,并且正在尝试使用 Slurp 和 JSON 做一些基本的事情。

我找到了一些代码(不起作用),我正在用它们作为例子来尝试学习一些基础知识。
以下代码的目的是从 Ipinfo.io 获取一些 JSON 数据,然后仅从中提取城市名称并打印出来。
命名空间错误太多,我甚至无法测试实际的代码。:-(`)

任何帮助都将非常感激!:-)
Jason

(ns my-namespace

(:require [clojure.core :as core]
			[clojure.data.json :as json]))

(defn get-city [ip-addr]

(let [resp (core/slurp (str "https://ipinfo.io" ip-addr "/json"))
	city-name (->> resp 
			(json/read-str)
			:city)]
(core/prn city-name)
city-name))

1 答案

0 投票

你几乎是成功的!以下是一些要注意的事项

  1. 不需要 require clojure.core,它在每个命名空间中都是自动导入的,因此只需这样

    (ns my-namespace (:require [clojure.data.json :as json]))

就足够了。

  1. 你似乎遗漏了主机名后的 /。

  2. 默认情况下,data.json 将以字符串键读取 JSON,所以除了 :city 部分, everything 上面的代码都是正确的。在 Clojure 中与 REPL 交互式地一步步进行可以很有帮助 - 这样你就可以快速看到 read-str 返回了一个带有字符串键的映射。

  3. 要为此函数查找文档,请使用 (doc json/read-str) 查看文档字符串,它指向 read 此处有文档: (doc json/read)。有一个 :key-fn 选项,其默认值为 identity,但你可以使用 keyword 函数来构建关键字键。这样做之后,您将想要使用 -> 而不是 ->> 来连接。

将所有这些组合起来

(ns my-namespace
  (:require [clojure.data.json :as json]))

(defn get-city [ip-addr]
  (let [resp (slurp (str "https://ipinfo.io/" ip-addr "/json"))
        city-name (-> resp 
                      (json/read-str :key-fn keyword)
                      :city)]
    city-name))
尝试了,但仍然收到ns错误。这是错误信息...

user=> (ns my-namespace (:require [clojure.data.json :as json]))
执行错误(FileNotFoundException)在 my-namespace/eval138$loading (REPL:1)。
无法在类路径中找到 clojure/data/json__init.class,clojure/data/json.clj 或 clojure/data/json.cljc。
此代码需要在类路径上具有data.json库。依赖信息可在https://github.com/clojure/data.json/#releases-and-dependency-information找到,但为了知道如何添加它,我需要了解您如何开始您的REPL。
我只是用  clj 启动了 repl。
我可能应该使用 lein
好了!我通过执行
clj -Sdeps '{:deps {org.clojure/data.json {:mvn/version "2.4.0"}}}' 启动了 clj

程序还有一些问题...
实验中...
我正在逐步解决...
这有效
(print (slurp (str "https://ipinfo.io/" ip "/json")))

但是,如果创建一个函数,我似乎无法正确传递IP地址
(defn mytest [ip]
(print (slurp (str "https://ipinfo.io/" ip "/json"))))

mytest 24.80.129.110
#object[my_namespace$mytest 0x2e8a1ab4 "my_namespace$mytest@2e8a1ab4"]
在(REPL:18:0)处读取源代码时出现语法错误。
无效的数字:24.80.129.110

mytest "24.80.129.110"
#object[my_namespace$mytest 0x2e8a1ab4 "my_namespace$mytest@2e8a1ab4"]
"24.80.129.110"
by
Clojure中函数调用通常需要用括号包围,并且ip必须是一个字符串才能是有效的值,所以

(mytest "24.80.129.110")
by
哦!我真的不敢相信我做了那件事!
谢谢!
...