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 函数来构造关键字键。一旦你这样做,你就想使用->而不是->>来链接first。

汇总一下

(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参数
(定义函数 mytest [ip]
(打印 (slurp (str "https://ipinfo.io/" ip "/json"))) )

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

mytest "24.80.129.110"
#对象[my_namespace$mytest 0x2e8a1ab4 "my_namespace$mytest@2e8a1ab4"]
"24.80.129.110"
by
Clojure 中的函数调用总是涉及使用括号包围,而 ip 必须是字符串才能是有效的值,所以

(mytest "24.80.129.110")
by
OMG!我真不敢相信我做了这样的事情!
谢谢!
...