我正在努力获取正确的类型提示,以避免在从数据库查询中编写文本文件输出时发出反射警告。
我试图在调用每个函数之前放置^ 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 - "))))
答案 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方法调用的歧义。 )