clojure-conj不';似乎没有给向量增加价值

clojure-conj不';似乎没有给向量增加价值,clojure,Clojure,我编写了一个函数,它以目录作为输入并返回文件列表 (ns musicdb.filesystem) (import '(java.io.File) '(java.net.url) '(java.io)) (use 'clojure.java.browse) (require '[clojure.string :as str]) (defn getFiles "get a list of all files" [searchPath] (def directory

我编写了一个函数,它以目录作为输入并返回文件列表

(ns musicdb.filesystem)
(import '(java.io.File) '(java.net.url) '(java.io))
(use 'clojure.java.browse)
(require '[clojure.string :as str])

(defn getFiles
    "get a list of all files"
    [searchPath]
        (def directory (clojure.java.io/file searchPath))
        (def files (file-seq directory))
        (def fonly (filter (fn [x]
            (. x isFile)) files))
        (def names [])
        (doseq [x fonly] 
            (conj names (. x toString)) ;doesn't seem to work
            (println (. x toString))) ;but this DOES print the file path
        names)
这里唯一不起作用的是conj呼叫

这是我的测验

(ns musicdb.core-test
  (:require [clojure.test :refer :all]
            [musicdb.core :refer :all]
            [musicdb.filesystem :refer :all]))

(deftest test_0
  (testing "getFiles returns valid result"
    (is (> (count (getFiles "/home/ls/books/books")) 1))
    (doseq [i (take 5 (getFiles "/home/ls/books/books"))] (searchBook i))))

此测试失败,并显示
getFiles
的返回值为空。

names
是一个不可变的向量
(conj name(.x toString))
创建一个新向量,但不使用它。您的代码还有其他问题:

  • 您不想使用
    doseq
    。它的副作用,如打印出来的东西。如果您正在创建一个集合,通常不需要在clojure中进行迭代,或者如果您进行了迭代,则可以使用不可变的累加器、循环和递归
  • 您不想使用嵌套的def。您正在定义全局变量,您需要的是函数局部变量。使用
    let
  • clojure的命名风格是使用破折号而不是驼峰大小写(次要,只是一种约定)
  • 您似乎没有在这段代码中使用java.io导入
  • 通常使用
    不是一个好主意,除非您使用
    :仅
    将其限制为几个显式命名的函数。这是为了避免在代码中查看非限定名称时产生混淆,因为您不知道它来自何处
你想要这样的东西:

(defn get-files [search-path]
  (let [directory (clojure.java.io/file search-path)
        files (file-seq directory)
        fonly (filter #(.isFile %) files)]
   (map #(.toString %) fonly)))

conj
返回在末尾添加元素的新向量。您正在创建一个向量并将其丢弃。谢谢。因此,解决方案是:(def名称(conj名称(.x toString)),这可以工作,但不是惯用的Clojure。看我的答案。我是clojure的新手,这很有帮助。非常感谢。