【问题标题】:Clojure edit value of vector within functionClojure编辑函数内向量的值
【发布时间】:2023-04-03 05:19:01
【问题描述】:

我有空值的变量卡:

(def cards [0 0 0])

我试图在函数中将卡片的值(取决于输入)设置为 3。 这就是为什么我有以下代码:

(defn parse-int [s]
  (Integer. (re-find  #"\d+" s )))

(defn changevalue [] (assoc cards (parse-int (read-line)) 3)) 
(changevalue) 

但是当我执行问题并在输入 1 中键入时,该函数不会更改键 1 的值,当我打印它时,它仍然是 0 0 0 。我该如何解决?

我确定 parse-int 有效,我从以下地址获得:In Clojure how can I convert a String to a number?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    首先,只需使用Integer/parseInt 解析输入:

    (defn change-value [cards]
      (let [s (read-line)]
        (assoc cards (Integer/parseInt s) 3)))
    

    此函数返回cards副本,其中一个元素已更改。请记住,cards 是一个向量,它是不可变的。 一旦创建,您将无法更改它。

    您写道“该函数不会更改键 1 的值,当我打印它时,它仍然是 0 0 0 。我该如何解决这个问题?”你不修复它,你拥抱不变性。不要试图改变cards。使用change-value 返回的修改后的副本:

    (def cards [0 0 0])
    (def changed-cards (change-value cards))
    
    (println cards)
    (println changed-cards)
    

    如果你真的,真的真的需要可变性,你可以使用atom,但这不应该是你的第一选择。 Clojure 是一种非常强调不变性的函数式语言。顺其自然,而不是试图对抗语言。

    【讨论】:

    • 如何让函数“change-value”返回新卡片?
    • @Jelle 我发布的功能可以。请记住,函数中的最后一个表单会自动返回。尝试运行我发布的所有代码。
    【解决方案2】:

    Clojure 的数据结构几乎是不可变的。 在 clojure 中,对变异值的替换受到严格限制。 如果你想要可变数据结构,你可以使用Java的可变数据结构或者clojure的{atom,ref,var}。

    如果你真的想改变卡片,试试这个:

    (def cards (atom [0 0 0]))
    (defn change-cards! [idx] (swap! cards assoc idx 3))
    (change-cards! 2)
    @cards
    #_"here is no parseint to simplify your problem"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-03
      • 2013-02-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多