2014-09-24 45 views
1

我以爲我會嘗試core.typed希望在下面的代碼中刪除:pre條件。如何獲取core.typed以傳遞以下SHA256代碼?

(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 /籤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來傳遞下面的命名空間。如果你還解釋了這些錯誤的含義,以及當我看到它們時應該考慮的內容,我會更加感激。謝謝。

回答

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個可能的方法是core.typed已確定爲(.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"))