我正在努力获得正确的类型提示,以避免在从数据库查询写入文本文件输出时出现反射警告。
我试图在调用每个函数之前放置 ^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 - "))))
Run Code Online (Sandbox Code Playgroud)
反射警告告诉您,您需要明确write要在 中调用哪个方法#(.write wrtr (row-fn %))。所以你需要输入提示wrtr和(row-fn %):
#(.write ^java.io.Writer wrtr ^String (row-fn %))
Run Code Online (Sandbox Code Playgroud)
顺便说一下,向fn表单或函数文字添加类型提示没有任何效果。(好吧,添加原始提示确实会使结果函数实现相关clojure.lang.IFn$[OLD]+接口,但这些提示需要附加到参数向量和/或命名参数的各个符号。)
(相比之下,向defn表单中的函数名称添加类型提示确实会在结果变量上放置:tag元数据;这将被编译器用来消除 Java 方法调用的歧义。)
| 归档时间: |
|
| 查看次数: |
1589 次 |
| 最近记录: |