2016-12-07 6 views
3

私はチャットクライアント/サーバーを作成しています。ソケットを取得し、ソケットに書き込むために使用できるclojure.core.async /チャンネルを戻すコードを持っています。もっと簡単に。Clojureはリフレクション警告デンプサイト型のヒントを与えます

私の問題は、タイプヒントがあるにもかかわらず、.writeへの呼び出しを解決できないという反射の警告が表示されることです。

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

は与える:

Reflection warning, C:\Users\slomi\IdeaProjects\chat\src\chat\main.clj:44:5 - call to method write on java.io.PrintWriter can't be resolved (argument types: unknown). 

私はかかわらず、それがどんな明確にすることができるかわかりません。 p-outmessageの両方が明示的に示唆されています。不思議なことに、flushへの電話は問題ありません。

どうすれば解決できますか?

答えて

5

goは実際にあなたのコードをステートマシンに書き換えます(macroexpand-1で変換を調べることはできますが、その結果はかなり長いのでここには含めていません)。残念ながら、この変換は型ヒントを保持していないようです。それはgoによって書き換えられないので、

たぶん、そこよりよい解決策だが、あなたは、独自の関数にコールを引き出した場合、あなたはそれをtypehintことができます。

(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)) 
+0

ああ!それも考えなかった。いいキャッチ!それはその後しなければならないでしょう。ありがとう。 – Carcigenicate

関連する問題