为什么我的字符串函数返回clojure.lang.LazySeq@xxxxxx?

use*_*853 14 clojure

我使用leiningen REPL定义了以下3个函数:

(defn rand-int-range [floor ceiling] (+ floor (rand-int (- ceiling floor))))

(defn mutate-index
  "mutates one index in an array of char and returns the new mutated array"
  [source idx]
  (map
    #(if (= %1 idx)
       (char (+ (int %2) (rand-int-range -3 3)))
       %2)
    (iterate inc 0)
    source))

(defn mutate-string
  [source]
  (str
    (mutate-index
      (.toCharArray source)
      (rand-int (alength (.toCharArray source))))))
Run Code Online (Sandbox Code Playgroud)

当我运行时(mutate-string "hello"),而不是REPL打印出变异的字符串,它打印出clojure.lang.LazySeq@xxxxxx,其中'xxxxx'是一个随机的数字和字母序列.我希望它能打印出像"hellm"这样的东西吗?这真的像我想的那样给了我一个字符串吗?如果是,我如何让REPL向我显示该字符串?

Jus*_*mer 17

1)要将字符序列(mutate-index返回的字符串)转换为字符串,请使用apply str而不是仅使用str.后者操作对象,而不是序列.

(str [\a \b \c])
=> "[\\a \\b \\c]"

(apply str [\a \b \c])
=> "abc"
Run Code Online (Sandbox Code Playgroud)

2)字符串是可选的,这意味着你可以直接使用mapfilter它们一样的序列函数,而不需要像.toCharArray.

3)考虑使用map-indexedStringBuilder完成你想要做的事情:

(apply str (map-indexed (fn [i c] (if (= 3 i) \X c)) "foobar"))
=> "fooXar"

(str (doto (StringBuilder. "foobar") (.setCharAt 3 \X)))
=> "fooXar"
Run Code Online (Sandbox Code Playgroud)


Ver*_*erg 8

发生这种情况,因为map函数返回一个惰性序列,该字符串reprsentation只是类名和散列(clojure.lang.LazySeq@xxxxxx).

为了获得原始工作,您需要首先评估延迟序列.通过使用(应用str ...)像贾斯汀一样建议应该发生,你应该得到正确的结果.

否则通常如果由于未评估延迟序列而发现类似问题,则应尝试函数doall,这会强制执行惰性序列的评估