Clojure giving reflection warnings depsite type hints

I'm writing a chat client/server, and have the following code that takes a socket, and gives back a clojure.core.async/channel that can be used to write to the socket more easily.

My problem is, despite being type-hinted, I still get reflection warnings that the call to .write can't be resolved.

(ns chat.main
  (:require [clojure.core.async :as a :refer [>! >!! <! <!! go thread chan]])

  (:import [java.net Socket ServerSocket]
           [java.io InputStream BufferedReader InputStreamReader OutputStream BufferedOutputStream PrintWriter]))

(set! *warn-on-reflection* true)

(defn new-output-chan [^Socket sock]
  (let [^OutputStream out (.getOutputStream sock)
        ^PrintWriter p-out (PrintWriter. out)
        out-chan (chan)]
    (go
      (while (.isConnected sock)
        (let [^String message (<! out-chan)]
          (.write p-out message) ; <---------- Here
          (.flush p-out)))
      (a/close! out-chan))
    out-chan))

Gives:

Reflection warning, C:UsersslomiIdeaProjectschatsrcchatmain.clj:44:5 - call to method write on java.io.PrintWriter can't be resolved (argument types: unknown).

I don't know how I could make it any clearer though. Both p-out and message are explicitly hinted. Strangely, the call to flush is fine.

How can I resolve this?


The problem is that go actually rewrites your code into a state machine (you can inspect the transformation with macroexpand-1 , but the result is pretty lengthy, so I haven't included it here). Unfortunately, it looks like this transformation doesn't preserve the type hint.

Maybe there's a better solution, but if you pull out the call into its own function, you can typehint that, since it won't be rewritten by go :

(defn new-output-chan [^Socket sock]
  (let [^OutputStream out (.getOutputStream sock)
        ^PrintWriter p-out (PrintWriter. out)
        out-chan (chan)
        write #(.write p-out ^String %)]
    (go
      (while (.isConnected sock)
        (let [message (<! out-chan)]
          (write message)
          (.flush p-out)))
      (a/close! out-chan))
    out-chan))
链接地址: http://www.djcxy.com/p/82582.html

上一篇: 创建ini文件,在PHP中写入值

下一篇: Clojure给反射警告depsite类型提示