请您在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返回了一个键为字符串的map。

  3. 要找到该函数的文档,使用(doc json/read-str)来查看docstring,其中会指向文档:(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]
打印(读取字符串 "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"
在Clojure中调用函数时总是需要在两侧加上括号,并且ip需要是一个字符串才能代表有效的值,所以

(mytest "24.80.129.110")
OMG!我都不敢相信我这么做!
谢谢!
...