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 部分,其他一切正常。在 Clojure 中,与 REPL 交互式地逐步工作是很有帮助的 - 你可以快速看到 read-str 返回了一个带有字符串键的映射。

  3. 要查找此函数的文档,使用 (doc json/read-str) 查看文档字符串,它引用了代码: (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,使其正常运行:
clj -Sdeps '{:deps {org.clojure/data.json {:mvn/version "2.4.0"}}}'

程序仍有一些问题...
正在尝试...
我正在逐步分析。
这行代码可以运行
(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
哦!我真的不敢相信我那样做了!
谢谢!
...