Clojure 2024 状态调查中分享您的想法!

欢迎!请在关于页面查看更多关于这个平台的信息。

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)查看文档字符串,其中引用了read,该文档在这里:(doc json/read)。有一个 :key-fn 选项,默认为 identity,但你可以使用 keyword 函数来构造关键字键。一旦这样做了,你将想要使用 -> 而不是 ->> 来thread 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地址。
(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
天哪!我真的没想到会这么做!
谢谢!
...