如何让core.typed传递以下SHA256代码?

时间:2014-09-24 02:19:05

标签: clojure clojure-core.typed

我以为我会尝试使用core.typed,希望在以下代码中删除:pre条件。

(ns quizry.sha256
  (:require
   [clojure.core.typed :as ct])
  (:import
   [java.security MessageDigest]))

(defn utf8-array
  "input as an array of UTF-8 bytes"
  [input]
  {:pre [(string? input)]}
  (.getBytes input "UTF-8"))

(defn sha256-digest
  "sha-256 array digest of input"
  [input]
  {:pre [(string? input)]}
  (let [hasher (MessageDigest/getInstance "SHA-256")]
    (->> input utf8-array (.update hasher))
    (.digest hasher)))

(ct/ann sha256 [String -> String])

(defn sha256
  "generates the sha256 string hash of input"
  [input]
  {:pre [(string? input)]}
  (let [digest (-> input sha256-digest seq)]
    (apply str (map #(format "%02x" (bit-and % 0xff)) digest))))

如果我运行(clojure.core.typed / check-ns),我会得到以下内容:

Start collecting quizry.sha256
Finished collecting quizry.sha256
Collected 1 namespaces in 621.542571 msecs
Not checking clojure.core.typed (tagged :collect-only in ns metadata)
Start checking quizry.sha256
Checked quizry.sha256 in 1337.109049 msecs
Checked 2 namespaces (approx. 2326 lines) in 1990.843467 msecs
Type Error (quizry/sha256.clj:11:3) Unresolved instance method invocation 

Add type hints to resolve the host call.

Suggested methods:

 java.lang.String
 \
  public byte[] getBytes()
  public void getBytes(int, int, byte[], int)
  public byte[] getBytes(java.nio.charset.Charset)
  public byte[] getBytes(java.lang.String).

Hint: use *warn-on-reflection* to identify reflective calls
in: (.getBytes input UTF-8)


Type Error (quizry/sha256.clj:18:5) Unresolved instance method invocation .

Hint: use *warn-on-reflection* to identify reflective calls
in: (.update hasher (utf8-array input))


Type Error (quizry/sha256.clj:19:5) Cannot call instance method java.security.MessageDigest/digest on type (clojure.core.typed/U java.security.MessageDigest nil)
in: (.digest hasher)


Type Error (quizry/sha256.clj:28:22) Static method clojure.lang.Numbers/and could not be applied to arguments:


Domains:
    ct/AnyInteger ct/AnyInteger

Arguments:
    ct/Any (ct/Value 255)

Ranges:
    java.lang.Long

in: (clojure.lang.Numbers/and p1__36892# 255)
in: (format %02x (clojure.lang.Numbers/and p1__36892# 255))
uizry/sha256.clj:28:2

ExceptionInfo Type Checker: Found 4 errors  clojure.core/ex-info (core.clj:4403)

我是core.typed的新手,并没有真正理解错误。我希望让core.type传递以下命名空间。如果您还解释了这些错误的含义,以及我看到它们时应该思考的内容,我将不胜感激。谢谢。

1 个答案:

答案 0 :(得分:2)

未解决的反射是core.typed中的类型错误。

这就是core.typed告诉你它的反射方式,以及你想要调用哪些方法的最佳猜测。

Suggested methods:

 java.lang.String
 \
  public byte[] getBytes()
  public void getBytes(int, int, byte[], int)
  public byte[] getBytes(java.nio.charset.Charset)
  public byte[] getBytes(java.lang.String).

Hint: use *warn-on-reflection* to identify reflective calls
in: (.getBytes input UTF-8)

因此java.lang.String上有4种可能的方法,核心类型已经为(.getBytes input UTF-8)调用确定了。你显然想要一个String参数的那个,所以像往常一样添加类型提示来解决方法。

(defn utf8-array
  "input as an array of UTF-8 bytes"
  [^String input]
  {:pre [(string? input)]}
  (.getBytes input "UTF-8"))