String `clojure中的.split`方法返回意外结果

String `clojure中的.split`方法返回意外结果,string,clojure,String,Clojure,对于类项目的一部分,我需要读取Clojure中表示图形的文件。下面是一个示例文件。我可能读入的所有文件的文件结构都是这样的 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 我遇到的问题是试图基于空格分割一行。在我的回复中,我已经完成了 finalproj

对于类项目的一部分,我需要读取Clojure中表示图形的文件。下面是一个示例文件。我可能读入的所有文件的文件结构都是这样的

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
我遇到的问题是试图基于空格分割一行。在我的回复中,我已经完成了

finalproject.core> (.split "e 1 2" " ")
#<String[] [Ljava.lang.String;@180f214>
目前,我对这个模块的整个实现都是,如果我能正确使用
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

关于哪里出错的建议?

在下面的示例中,您的返回值是一个字符串类型的数组

finalproject.core> (.split "e 1 2" " ")
#<String[] [Ljava.lang.String;@180f214>
您还可以使用内置的
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
按索引访问列表中的元素<代码>(获取拆分行1)将从索引1处的
拆分行
获取元素,以此类推

您将在此处看到另一个问题:

((read-string first-str) (read-string second-str))
如果我正确地阅读了您的代码,那么最终将调用一个数字,就像调用一个函数一样,并使用另一个数字作为参数。也许您打算返回一对数字

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

如果未使用
(要求'[clojure.string:as string])
时未使用
clojure.string.split
函数,则正在使用什么
split
函数?//
(使用'clojure.java.io)
(require'[clojure.string:as string])
之间的区别是什么?
符号表示方法调用,它是本机java split字符串返回的值。split实际上是一个字符串数组–
string[]
,或
[Ljava.lang.String;
在较低级别的JVM行话中,而不是
java.util.List
。此外,
(vec(.split…)
在这里更可取,因为对于短向量(最多32项长)
vec
只需在数组周围包装一个向量(将其用作新向量的尾部)。当然,这只有在已知数组不会被修改的情况下才可以,在本例中就是这样。(
string/split
使用Clojure实现细节实现,在这方面类似于
vec
require
use
之间的区别在其他地方有详细介绍,但简短的版本是我们更喜欢
require
,因为它使函数的来源更加明确,并避免了多个名称空间具有相同名称的不同定义的问题
((read-string first-str) (read-string second-str))
[(read-string first-str) (read-string second-str)]