{:f-6ren">
gpt4 book ai didi

Clojure:使用 assoc-in 的结果不一致

转载 作者:行者123 更新时间:2023-12-04 23:22:45 24 4
gpt4 key购买 nike

有人可以使用 (assoc-in) 解释以下结果背后的原因吗? ?

(assoc-in {:foo {:bar {:baz "hello"}}} [:foo :bar] "world")
=> {:foo {:bar "world"}}

(assoc-in {:foo {:bar nil}} [:foo :bar :baz] "world")
=> {:foo {:bar {:baz "world"}}}

(assoc-in {:foo {:bar "hello"}} [:foo :bar :baz] "world")
=> ClassCastException java.lang.String cannot be cast to clojure.lang.Associative clojure.lang.RT.assoc (RT.java:702)

显然我可以替换 map 甚至 nil使用另一种数据类型(例如字符串),但我不能用映射替换数据类型(例如字符串),因为它需要该数据类型已经是映射。

人们将如何解决这个问题?我想实现以下目标:
(assoc-in {:foo {:bar "hello"}} [:foo :bar :baz] "world")
=> {:foo {:bar {:baz "world"}}}

最佳答案

assoc-in assoc 之上实现.您可以替换 map 和nil因为 assoc对它们起作用:

(assoc {} :foo :bar)  ;=> {:foo :bar}
(assoc nil :foo :bar) ;=> {:foo :bar}

但是 assoc不适用于字符串:
(assoc "string" :foo :bar) ;=> ClassCastException

顺便说一句, the definitionassoc-in很优雅:
(defn assoc-in
;; metadata elided
[m [k & ks] v]
(if ks
(assoc m k (assoc-in (get m k) ks v))
(assoc m k v)))

如果您需要替换 assoc 的值不能被调用,您需要在更浅的一层上操作并替换整个 map 而不仅仅是值:
(assoc-in {:foo {:bar "hello"}} [:foo :bar] {:baz "world"})
;=> {:foo {:bar {:baz "world"}}}

如果 map 中还有其他值您不想通过替换整个内容而丢失,您可以使用 update-in assoc :
(update-in {:foo {:bar "hello"}} [:foo] assoc :baz "hi")
;=> {:foo {:bar "hello", :baz "hi"}}

关于Clojure:使用 assoc-in 的结果不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19692764/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com