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

欢迎!请查看关于页面以了解有关此功能的更多信息。

0 投票
Clojure
重新标记

我已经有一段时间没有写Clojure了,所以我的技能已经生疏。

基本上,我正在尝试编写代码以对REST API进行HTTP GET,并将返回的JSON对象数组转换为Clojure数据(即Map列表)。JSON数据看起来像这样

[
    {
        "id": 1,
        "category": "technical",
        "asin": "0131103628",
        "title": "C Programming Language, 2nd Edition",
        "publication_date": "1988-04-01T00:00:00Z",
        "review": "The C book.",
        "created_at": "2020-03-06T20:48:00Z"
    },
    {
        "id": 2,
        "category": "technical",
        "asin": "0387966080",
        "title": "The Science of Fractal Images",
        "publication_date": "1988-07-19T00:00:00Z",
        "review": "The book on fractal algorithms.  Sadly, no longer in print.  I had to search high and low for a used copied.",
        "created_at": "2020-03-06T20:48:00Z"
    },
    // etc..
]

我使用http-kit(我也尝试过clj-http)来调用REST API并返回体。之后,我尝试将体转换为Clojure数据。我尝试使用过org.clojure/data.jsoncheshire。然而,我认为数据没有被正确转换。

(defn get-books-body
  []
  (:body @(client/get books-url api-options)))

(defn get-books
  []
  (parse-string get-books-body true))

当尝试显示体类型时,它显示为地址而不是字符串

clojure-json-test.core=> (type get-books-body)
clojure_json_test.core$get_books_body

并且我无法查看转换为JSON后的第一条记录

clojure-json-test.core=> (first get-books)
Execution error (IllegalArgumentException) at clojure-json-test.core/eval3169 (form-      init15378865171954877190.clj:1).
Don't know how to create ISeq from: clojure_json_test.core$get_books

有什么想法我知道我在哪里做错了?

1 答案

0 投票

选中
 
最佳答案

在你的示例中,你将 typefirst 应用于函数对象 get-books-bodyget-books,而不是调用函数。

同样的问题存在于 get-books 定义中,你未将字符串传递给 parse-string,而是传递了 get-books-body 变量引用的函数对象。在 Clojure 中,函数对象实际上是有效数据,所以这是合法的(这就是为什么函数类型是 clojure_json_test.core$get_books_body,它是实现该命名空间中 Clojure 函数的类),为什么尝试对函数对象应用 first(而不是期望的解析 JSON 序列结果调用函数)会失败,因为 Clojure 函数不实现序列协议。

我将 get-books 修改为实际调用函数以获取字符串结果。

(defn get-books
 []
 (parse-string (get-books-body) true))

然后同样尝试使用函数调用进行测试。

(type  (get-books-body))
(first (get-books))
谢谢!很高兴这件事如此简单。我想在我离开 Clojure 的期间,我忘了函数需要用括号括起来。
...