Clojure Reflection警告 - 写入的呼吁无法解决

时间:2014-04-23 12:34:02

标签: java clojure

我正在努力获取正确的类型提示,以避免在从数据库查询中编写文本文件输出时发出反射警告。

我试图在调用每个函数之前放置^ String类型提示,因为最终输出将命中磁盘上的文本文件。

反射警告发生在:row-fn行朝向函数末尾。我在同一行上发表了评论Reflection warning, dbdump/dbdump.clj:157:44 - call to write can't be resolved.

我怎样摆脱这个警告?我认为使用大型数据集时会产生性能成本。

(defn run-job [job-time-string db-spec config]
  (let [; {{{
        source-sql          (str "select * from " (:source-base-name config)(:table-name config))
        max-rows            (:max-rows            config)
        fetch-size          (:fetch-size          config)
        working-dir         (:working-dir         config)
        output-name           (str working-dir "/" job-time-string ".pipe" )
        field-delim         (:field-delim         config)
        row-delim           (:row-delim           config)
        log-report-interval (:log-report-interval config)
        row-count           (atom 0)  ; For state on rows
        db-connection       (doto (j/get-connection db-spec))
        statement           (j/prepare-statement db-connection source-sql :fetch-size fetch-size :concurrency :read-only :max-rows max-rows)
        start-in-millis     (System/currentTimeMillis)
        replace-newline (^String fn [s]
                          (if
                              (string? s)
                            (clojure.string/replace  s #"\n" " ")
                            s)) ; I'd prefer not to do this; Right now we can't load \n fields.
        row-fn          (^String fn [v]
                          (swap! row-count inc)
                          (when
                              (zero?
                               (mod @row-count log-report-interval))
                            (write-logs @row-count start-in-millis 3 (:table-name config) ))
                          (str (join field-delim (doall (map #(replace-newline %) v))) row-delim ))
        ]; }}}
    (with-open [^java.io.Writer wrtr (io/writer output-name )]
        (info "Fetching jdbc query..." )
        (info source-sql)
        (try
          (j/query db-connection [statement]
                   :as-arrays?    true
                   :result-set-fn vec
; Reflection warning, dbdump/dbdump.clj:157:44 - call to write can not be resolved.
                   :row-fn        ^String #(.write wrtr (row-fn %)))
          (catch Exception e
            (error (str "Error while fetching JDBC data." (.getMessage e)))
            (System/exit 9))))
    (write-logs @row-count start-in-millis 0 (str (:source-base-name config)  (:table-name config) " Completed - "))))

1 个答案:

答案 0 :(得分:4)

反射警告告诉您需要澄清write中要调用的#(.write wrtr (row-fn %))方法。因此,您需要输入提示wrtr(row-fn %)

#(.write ^java.io.Writer wrtr ^String (row-fn %))

顺便提一下,向fn表单或函数文字添加类型提示无效。 (好吧,添加原始提示会使得结果函数实现相关的clojure.lang.IFn$[OLD]+接口,但这些提示需要附加到参数向量和/或命名参数的各个符号。)

(相反,在defn表单中向函数名称添加类型提示确实会在生成的Vars上放置:tag元数据;编译器将使用它来消除Java方法调用的歧义。 )