gpt4 book ai didi

lisp - Clojure 变量和循环

转载 作者:太空宇宙 更新时间:2023-11-03 18:35:08 24 4
gpt4 key购买 nike

通过谷歌搜索,我发现不鼓励使用 while 循环或使用变量。

现在我实现了一个非常简单的算法,它将从输入流中读取字符并进行相应的解析:如果输入是 10:abcdefghej 它将解析出 10 然后读取下一个 10冒号后的字节。

我有点迷失的是如何重构它,使其不依赖于变量。


(defn decode-string [input-stream indicator]

(with-local-vars [length (str (char indicator) )
delimiter (.read input-stream )
string (str "")
counter 0 ]

(while (not(= (var-get delimiter) 58 ))
(var-set length (str (var-get length) (char (var-get delimiter)) ))
(var-set delimiter (.read input-stream )))

(var-set length (new BigInteger (var-get length)) )
(var-set counter (var-get length))

(while (not(zero? (var-get counter) ))
(var-set string (str (var-get string) (char (.read input-stream )) ))
(var-set counter (dec (var-get counter))))
(var-get string)))

另外,我知道声明变量的唯一方法是使用 with-local-vars 关键字。一开始就在一个 block 中定义所有变量是不是有点不切实际,还是我错过了一些关键点?

最佳答案

您正在编写的是具有类似 lisp 语法的 C 代码(无意冒犯)。用你不做来定义风格是非常明确的,但如果你不知道“好吧,那又如何呢?”这不是很有帮助

顺便说一下,我不知道 indicator 应该做什么。

这就是我解决这个问题的方法:

  1. 问题分为两部分:找到要读取的字符数,然后读取那么多字符。因此,我会写两个函数:read-countread-item,后者使用前者。

    (defn read-count [stream]  ;; todo  )(defn read-item [stream]  ;; todo  )
  2. read-item首先需要确定要读取的字符数。为此,它使用我们也将定义的便捷函数 read-count

    (defn read-item [stream]  (let [count (read-count stream)]    ;; todo    ))
  3. 在 Clojure 中,循环通常最好通过使用 looprecur 来处理。 loop 也绑定(bind)变量,如 letacc的意思是累加读取的item,但是注意不是原地修改而是每次迭代都重新绑定(bind)。

    (defn read-item [stream]  (loop [count (read-count stream)         acc ""]    ;; todo    (recur (dec count)        ; new value for count           (str acc c)))))    ; new value for acc
  4. 现在我们需要在那个循环中做一些事情:将 c 绑定(bind)到下一个字符,但是当 count 是时返回 acc 0. (zero?count)(= count 0) 相同。我为那些不熟悉它的人对 if 形式做了一些注释。

    (defn read-item [stream]  (loop [count (read-count stream)         acc ""]    (if (zero? count)                  ; condition        acc                            ; then        (let [c (.read stream)]        ; \          (recur (dec count)           ;  > else                 (str acc c)))))))     ; /
  5. 现在我们只需要read-count 函数。它使用类似的循环。

    (defn read-count [stream]  (loop [count 0]    (let [c (.read stream)]      (if (= c ":")          count          (recur (+ (* count 10)                    (Integer/parseInt c)))))))
  6. 在 REPL 上测试、调试、重构。 .read 真的返回字符吗?有没有更好的方法来解析整数?

我还没有测试过这个,我对 Clojure 没有任何经验和深入了解(我主要使用 Common Lisp)有点受阻,但我认为它展示了如何在“lispy”中解决此类问题“方式。请注意我是如何不考虑声明或修改变量的。

关于lisp - Clojure 变量和循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1054170/

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