Aut*_*ton 3 eclipse string vector clojure
我已经成功编写了一个函数,它将空格分隔的整数字符串转换为Clojure中的整数向量,但由于我(非常)新的函数式语言,我担心我仍然在考虑程序性.
该函数用于split对字符串进行标记,然后迭代通过返回的向量,将标记单独转换为整数,然后将它们附加到新向量.我正在使用,read-string因为输入是自我提供的,我并不真正关心安全性.
(defn parser [myStr]
;;counter
(def i 0)
;;tokenizes string and returns vector of tokens
(def buffer (clojure.string/split myStr #"\s"))
;;reads vector of strings as integers then appends them to a new vector x
(def x (vector-of :int))
(while ( < i (count buffer))
(def x (conj x (read-string (nth buffer i))))
(def i (inc i)))
(println x))
Run Code Online (Sandbox Code Playgroud)
我的代码有效,但我担心通过改变状态并迭代缓冲向量,我有点作弊并坚持我的程序根源.
是否有更优雅或功能性的方法来解决这个问题?
这里有一些非常值得注意的事情:
除非你有充分的理由def,defn否则不要在里面使用.这里的用例是不合理的.只需使用:let
(defn parser [myStr]
(let [i 0
buffer (clojure.string/split myStr #"\s")
x (vector-of :int)]
...)
Run Code Online (Sandbox Code Playgroud)
要查看区别是什么,运行您的函数,然后检查是什么i.def创建在函数退出后持久存在的全局变量,这会泄漏函数的状态并污染命名空间.
你正在使用read-string解析.不要那样做.只需使用Java Long/parseLong.read-string有eval行为,从来没有好处滥用.您也可以使用clojure.edn/read-string哪些可以读取Clojure结构和文字,但不执行代码.
while当您真正使用loop或使用许多其他功能方法时,您正在使用副作用.@ xs0基本上是正确的.我把你的功能写成:
(defn parser [myStr]
; The v in mapv means it returns a vector
; Just map returns a lazy seq
(mapv #(Long/parseLong %) (clojure.string/split myStr #"\s"))
Run Code Online (Sandbox Code Playgroud)
遗憾的是Long/parseLong需要将函数包装在函数中,因为Java互操作方法不能像普通的Clojure函数一样使用.
Long/parseLong如果您可以保证每个令牌split返回是可解析的,则只能安全使用.当然,如果没有这样的保证,你需要做一些错误处理,或者在尝试解析之前清理输入.
| 归档时间: |
|
| 查看次数: |
157 次 |
| 最近记录: |