clojure 中的 `.split` 方法 returns 意外结果

`.split` method in clojure returns unexpected results

对于 class 项目的一部分,我需要读入一个表示 Clojure 图形的文件。这是一个 link to 示例文件。我可能阅读的所有文件的文件结构都是这样的

c Unknown number of lines
c That start with "c" and are just comments
c The rest of the lines are edges
e 2 1
e 3 1
e 4 1
e 4 2
e 4 3
e 5 1
e 5 2

我遇到的问题是试图 split 基于空格的行。在我的 REPL 中我已经完成了

finalproject.core> (.split "e 1 2" " ")
#<String[] [Ljava.lang.String;@180f214>

我不确定它到底是什么意思。我认为它指的是 String[] 的内存位置,但我不确定为什么会这样显示。如果在拆分字符串前面插入一个 #,我认为这表示它是一个正则表达式,我会收到一个错误

finalproject.core> (.split "e 1 2" #" ")
ClassCastException java.util.regex.Pattern cannot be cast to java.lang.String 

目前我对这个模块的整个实现是,如果我能正确使用 split 函数,我很确定它会工作。

(defn lineToEdge [line]
  (cond (.startsWith line "e")
        (let [split-line (.split line " ")
              first-str (split-line 1)
              second-str (split-line 2)]
          ((read-string first-str) (read-string second-str)))))

(defn readGraphFile [filename, numnodes]
  (use 'clojure.java.io)
  (let [edge-list 
        (with-open [rdr (reader filename)]
          (doseq [line (line-seq rdr)]
           (lineToEdge line)))]
    (reduce add-edge (empty-graph numnodes) edge-list)))

我还没有机会以任何方式测试 readGraphFile,但是当我尝试将 lineToEdge 与一些虚拟输入一起使用时,我收到错误消息

finalproject.core> (lineToEdge "e 1 2")
ClassCastException [Ljava.lang.String; cannot be cast to clojure.lang.IFn

关于我哪里出错的建议?

在下文中,您的 return 值是一个字符串类型的数组。

finalproject.core> (.split "e 1 2" " ")
#<String[] [Ljava.lang.String;@180f214>

为了在Clojure中更方便的使用,可以将其放入vector中:

user=> (vec (.split "e 1 2" " "))
["e" "1" "2"]

您还可以使用内置的 clojure.string 命名空间:

user=> (require '[clojure.string :as string])
nil
user=> (string/split "e 1 2" #" ")
["e" "1" "2"]

您的堆栈跟踪源在这里:

(let [split-line (.split line " ")
      first-str (split-line 1)
      second-str (split-line 2)] ...)

这通过 .split 获取一个字符串数组,然后尝试调用它,就好像它是一个函数一样。也许您打算在这里使用 get 通过索引访问 List 的元素? (get split-line 1) 将从索引 1 处的 split-line 获取元素,等等

你会在这里看到另一个问题:

((read-string first-str) (read-string second-str))

如果我正确地阅读了你的代码,这将最终调用一个数字,就好像它是一个函数,另一个数字作为参数。也许你打算return一对数字?

[(read-string first-str) (read-string second-str)]