7

Javaコードのいくつかのレイヤーを介して相互運用しようとしているいくつかのClojureコードがあります(この場合、次java.nio.Pathの方法でjava.nio.file.WatchEvent<?>

(defn unroll-event
  [^WatchEvent event]
  { :kind (.kind event)
    :context (.context event)
    :path (-> event .context .toAbsolutePath .toString)})

このコードでは、私は type Hinted を持っているeventので、何が返されるべきかを理解できるはずであり、そのため、何を理解して何をすべきかを理解できるはずです。この場合、is defined はジェネリック型を返すので、 への呼び出しをタイプヒントできるかどうか疑問に思っています。、 、 、 、 、 にそれぞれ前置しようとしましたが、それでも警告が表示されます。.context.toAbsolutePath.toString.contextT.context^java.nio.file.Path.context^Path^String.toAbsolutePathtoString

Reflection warning, junkcode/core.clj:28 - reference to field toAbsolutePath can't be resolved.
Reflection warning, junkcode/core.clj:28 - reference to field toString can't be resolved.

この場合、何かできることはありますか?->マクロであり、その中にタイプヒントの特別なルールがあるためですか?

4

2 に答える 2

3

(-> x .blah ^String .bar)基本的に、に拡張され(^String .bar (.blah x))ますが、これは明らかにヒントが必要な場所ではありません。重要なのは、タイプヒントはどのコンテキスト(マクロなど)でも特別な動作をしないということです。これは、ソースコードシンボルに適用されるメタデータにすぎません。あなたの例->では、入力フォームにメタデータを配置して、出力フォームの目的の場所にメタデータを配置できる場所はありません。(-> ^Path (.context event) .toAbsolutePath str)したがって、たとえば、などの他のフォームを作成する必要があります。

また、Clojureの推論機能はジェネリック型について何も知らないため、method-returning-Tはmethod-returning-Objectとして扱われます。これは、ここでヒントを与える必要がある理由を説明しています。

于 2012-10-07T06:07:16.727 に答える
3

これが常に当てはまるかどうかはわかりませんが、Clojure 1.4.0、1.5.1、および 1.6.0 では、->括弧を使用する限り、いつでもタイプヒントを使用できます。

user=> (set! *warn-on-reflection* true)
true
user=> (fn [^java.nio.file.WatchEvent e] 
         (-> e ^java.nio.file.Path .context .toAbsolutePath))
Reflection warning, /private/var/folders/9_/wdph6m796zzc8trzcbtcmhrn5bjpt0/T/form-init8364673644863044068.clj:1:35 - reference to field toAbsolutePath on java.lang.Object can't be resolved.
#<user$eval1995$fn__1996 user$eval1995$fn__1996@8128f39>
user=> ; but no warning if we do
user=> (fn [^java.nio.file.WatchEvent e]
         (-> e ^java.nio.file.Path (.context) .toAbsolutePath))
#<user$eval1999$fn__2000 user$eval1999$fn__2000@4747e32a>

唯一の違いは、周囲の括弧.contextです。

于 2014-06-12T19:11:27.177 に答える