通过谷歌搜索,我发现不鼓励使用 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
应该做什么。
这就是我解决这个问题的方法:
问题分为两部分:找到要读取的字符数,然后读取那么多字符。因此,我会写两个函数:
read-count
和read-item
,后者使用前者。(defn read-count [stream] ;; todo ) (defn read-item [stream] ;; todo )
read-item
首先需要确定要读取的字符数。为此,它使用我们也将定义的便捷函数read-count
。(defn read-item [stream] (let [count (read-count stream)] ;; todo ))
在 Clojure 中,循环通常最好通过使用
loop
和recur
来处理。loop
也绑定(bind)变量,如let
。acc
的意思是累加读取的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
现在我们需要在那个循环中做一些事情:将
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))))))) ; /
现在我们只需要
read-count
函数。它使用类似的循环。(defn read-count [stream] (loop [count 0] (let [c (.read stream)] (if (= c ":") count (recur (+ (* count 10) (Integer/parseInt c)))))))
在 REPL 上测试、调试、重构。
.read
真的返回字符吗?有没有更好的方法来解析整数?
我还没有测试过这个,我对 Clojure 没有任何经验和深入了解(我主要使用 Common Lisp)有点受阻,但我认为它展示了如何在“lispy”中解决此类问题“方式。请注意我是如何不考虑声明或修改变量的。
关于lisp - Clojure 变量和循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1054170/