我只是想读一个标准的linux'/ etc/passwd'文件:拆分成记录.这似乎工作(所有行都回显到终端)但最后抛出一个异常?(见下文)
这项计划有什么用?
(use 'clojure.java.io) (use 'clojure.string) (defn process_file[infile] ( (defstruct user :username :password :uid :gid :comment :home_dir :shell) (def record_separator #":") (with-open [rdr (reader infile)] (doseq [line (line-seq rdr)] (def fields (split line record_separator) ) (def user_record (apply struct user fields) ) (println (user_record :username) ) ) ) ) ) ; main (process_file "/etc/passwd") [ after all the lines read have been output ] Exception in thread "main" java.lang.ClassCastException: clojure.lang.PersistentStructMap$Def cannot be cast to clojure.lang.IFn at clojure.lang.Var.fn(Var.java:392) at clojure.lang.Var.invoke(Var.java:419) at user$process_file.invoke(readfile.clj:15) at user$eval14.invoke(readfile.clj:26) at clojure.lang.Compiler.eval(Compiler.java:6514) at clojure.lang.Compiler.load(Compiler.java:6955) at clojure.lang.Compiler.loadFile(Compiler.java:6915) at clojure.main$load_script.invoke(main.clj:283) at clojure.main$script_opt.invoke(main.clj:343) at clojure.main$main.doInvoke(main.clj:427) at clojure.lang.RestFn.invoke(RestFn.java:408) at clojure.lang.Var.invoke(Var.java:415) at clojure.lang.AFn.applyToHelper(AFn.java:161) at clojure.lang.Var.applyTo(Var.java:532) at clojure.main.main(main.java:37) java version "1.7.0_21" OpenJDK Runtime Environment (IcedTea 2.3.9) (7u21-2.3.9-1ubuntu1) OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode) Clojure 1.4.0
Kyle Burton.. 7
在函数的整个主体周围有一组额外的括号.删除它看起来如下(虽然我不建议这样编写代码,见下文):
(defn process_file[infile] (defstruct user :username :password :uid :gid :comment :home_dir :shell) (def record_separator #":") (with-open [rdr (reader infile)] (doseq [line (line-seq rdr)] (def fields (split line record_separator)) (def user_record (apply struct user fields)) (println (user_record :username)))))
在你的程序中,你正在使用def
一个功能,这是不鼓励的.编写代码的一种更惯用的方法是使用命名空间,并在函数外部定义结构和记录分隔符,然后let
在函数中使用局部变量.以这种方式重新格式化代码如下所示:
(ns scratch (:require [clojure.java.io :as io] [clojure.string :as string])) (defstruct user-rec :username :password :uid :gid :comment :home-dir :shell) (def record-separator #":") (defn process-file [fname] (with-open [rdr (io/reader fname)] (doseq [line (line-seq rdr)] (let [fields (string/split line record-separator) user (apply struct user-rec fields)] (println (format "user: %s" user)))))) (process-file "/etc/passwd")
上面的代码运行,打印出为密码文件的每一行创建的结构.
在函数的整个主体周围有一组额外的括号.删除它看起来如下(虽然我不建议这样编写代码,见下文):
(defn process_file[infile] (defstruct user :username :password :uid :gid :comment :home_dir :shell) (def record_separator #":") (with-open [rdr (reader infile)] (doseq [line (line-seq rdr)] (def fields (split line record_separator)) (def user_record (apply struct user fields)) (println (user_record :username)))))
在你的程序中,你正在使用def
一个功能,这是不鼓励的.编写代码的一种更惯用的方法是使用命名空间,并在函数外部定义结构和记录分隔符,然后let
在函数中使用局部变量.以这种方式重新格式化代码如下所示:
(ns scratch (:require [clojure.java.io :as io] [clojure.string :as string])) (defstruct user-rec :username :password :uid :gid :comment :home-dir :shell) (def record-separator #":") (defn process-file [fname] (with-open [rdr (io/reader fname)] (doseq [line (line-seq rdr)] (let [fields (string/split line record-separator) user (apply struct user-rec fields)] (println (format "user: %s" user)))))) (process-file "/etc/passwd")
上面的代码运行,打印出为密码文件的每一行创建的结构.