Почему моя строковая функция возвращает clojure.lang.LazySeq@xxxxxx? - PullRequest
14 голосов
/ 30 октября 2011

Я определил следующие 3 функции, используя leiningen REPL:

(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))))))

Когда я запускаю (mutate-string "hello"), вместо REPL распечатывается мутированная строка, он распечатывает clojure.lang.LazySeq@xxxxxx, где «xxxxx» - это случайная последовательность цифр и букв.Я ожидаю, что вместо этого он напечатает что-то вроде «hellm». Это действительно возвращает мне строку, как я думаю?Если это так, как я могу получить REPL, чтобы показать мне эту строку?

Ответы [ 3 ]

17 голосов
/ 30 октября 2011

1) Чтобы преобразовать последовательность символов (то, что возвращает mutate-index) в строку, используйте apply str, а не просто str.Последний работает с объектами, а не с последовательностями.

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

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

2) Строки являются секвенируемыми, что означает, что вы можете использовать функции последовательности, такие как map и filter, непосредственно без них, например .toCharArray.

3) Подумайте об использовании map-indexed или StringBuilder, чтобы выполнить то, что вы пытаетесь сделать:

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

(str (doto (StringBuilder. "foobar") (.setCharAt 3 \X)))
=> "fooXar"
8 голосов
/ 01 ноября 2011

Это происходит потому, что функция map возвращает ленивую последовательность, в которой строковое представление представляет собой просто имя класса и хеш (clojure.lang.LazySeq@xxxxxx).

Для того, чтобы получить оригинальную работу, вам нужно сначала оценить ленивую последовательность. Используя (применить стр ...), как советовал Джастин, это должно произойти, и вы должны получить правильный результат.

В противном случае, если вы видите похожие проблемы из-за отсутствия оценки ленивой последовательности, вы должны попробовать функцию doall, которая вызывает оценку ленивой последовательности

0 голосов
/ 30 января 2014

Всякий раз, когда я хочу получить строковое значение отложенной последовательности, я использую clojure.core/pr-str:

user=> (clojure.tools.logging/infof "This is a lazy seq [%s]" (take 5 (range 100)))
INFO  user - This is a lazy seq [clojure.lang.LazySeq@1b554e1]
nil
user=> (clojure.tools.logging/infof "This is a lazy seq [%s]" (pr-str (take 5 (range 100))))
INFO  user - This is a lazy seq [(0 1 2 3 4)]
nil
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...