如何翻译以下代码
while ((readInteger = fileInputStream.read()) != -1) {
.....
}
在clojure中?我需要在代码的其他部分中使用readInteger的值,但是'!= -1'需要在while条件内进行。
答案 0 :(得分:6)
使事物适应Clojure语法的一些通用模式
(
移动到函数或操作符的左侧。( )
所以你可以这样开始:
(while (not= (.read fileInputStream) -1 ... and so on.
然后,因为您需要在代码中稍后使用readInteger
值,所以我们来谈谈命名值和循环。如果您只想读取一次值并给它起一个名字就可以这样做:
(let [readInteger (.read fileInputStream)]
... your code here)
由于你想在一个循环中完成它,那么让我们使用loop
代替let:
(loop [readInteger (.read fileInputStream)]
... your code here
(if (not= readInteger -1)
(recur (.read fileInputStream))))
或for
(不是其他语言的“for循环”)
(for [readInteger (repeatedly #(.read fileInputStream))
:while (not= readInteger -1)]
... do somethign with readInteger ...)
用于生成结果序列,而不是像在其他语言中那样循环。
然后,clojuring的下一步是考虑如何分割读取数据来处理它。我们可以:
类似的东西:
(let [data (line-seq fileInputStream)]
(map #(Integer/parseInt %) data)
...)
标准库中有许多功能可以将很多东西转换成序列,还有一些函数可以用序列来完成很多事情。
答案 1 :(得分:3)
请勿使用## [[1]]
## [1] "WXYZ" "AB" "A4K7" "01" "A" "13" "B" "J29Q" "10"
来解决此问题,这需要您在循环开始时进行测试。相反,考虑一个递归函数,它可以在其身体的任何部分决定是否进行递归调用。可以使用while
/ loop
将任何迭代循环转换为尾递归函数;这是一个如何使用循环执行此操作的示例。
recur
答案 2 :(得分:2)
以下是两个类似的例子,如amalloy建议:
(ns xyz...
(:require [clojure.java.io :as io] )
(:import [java.io StringReader] ))
(newline) (newline)
(let [reader-2 (io/reader (StringReader. "first")) ]
(loop []
(let [curr-char-int (.read reader-2)]
(when (not= -1 curr-char-int)
(print (char curr-char-int) " ")
(recur)))))
(newline) (newline)
(let [reader-2 (io/reader (StringReader. "second")) ]
(loop [curr-char-int (.read reader-2)]
(when (not= -1 curr-char-int)
(print (char curr-char-int) " ")
(recur (.read reader-2)))))
结果:
> lein run
f i r s t
s e c o n d
在第一种情况下,它需要额外的let
语句,但不会像第二种情况那样复制(.read reader-2)
部分。
答案 3 :(得分:0)
使用线程宏:
(->> (repeatedly #(.read fs))
(take-while (partial not= -1))
(map str))
用你想要操作的任何函数替换(map str) 在流上。例如,要计算总和:
(->> (repeatedly #(.read fs))
(take-while (partial not= -1))
(reduce +))