读取文本文件时的Clojure异常

 日韩潮衣一手临终批发 发布于 2023-02-07 17:44

我只是想读一个标准的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")

上面的代码运行,打印出为密码文件的每一行创建的结构.

1 个回答
  • 在函数的整个主体周围有一组额外的括号.删除它看起来如下(虽然我不建议这样编写代码,见下文):

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

    上面的代码运行,打印出为密码文件的每一行创建的结构.

    2023-02-07 17:48 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有