(if (string? x)
(inc x)
10)
2019 年 1 月 31 日
ClojureScript 團隊
Spec instrumentation (cljs.spec.test.alpha/instrument
和相關功能) 不再需要 test.check
。如果您使用 cljs.spec.test.alpha/check
,則需要 test.check
的資料產生功能;在這種情況下,您需要引入 clojure.test.check
和 clojure.test.check.properties
命名空間。
cljs.spec.test.alpha/check
API 中與 Spec 使用 test.check
相關的關鍵字現在以 clojure.spec.test.check
限定,從而與 Clojure 對齊。仍然支援先前使用 clojure.test.check
限定的方式。
Clojure 1.10 中新增的改進的例外基礎架構已在此版本中移植到 ClojureScript。
此版本新增了一個新的 clojure.edn
命名空間,它將功能委派給 cljs.reader
。這有助於編寫可移植的 Clojure / ClojureScript 原始碼,並利用 clojure.edn/read
和 clojure.edn/read-string
。
現在,型別推斷演算法會在推斷條件運算式中使用的區域變數的型別時考慮核心謂詞。
例如,在
(if (string? x)
(inc x)
10)
因為 x
滿足 string?
,所以會在 then 分支中推斷為字串型別 (因此會發出警告,因為 inc
被應用於它)。
因為 cond
和 when
是基於 if
建構的巨集,所以謂詞誘導的推斷也適用於涉及 cond
和 when
的運算式。
除了核心謂詞外,謂詞誘導的型別推斷也適用於 instance?
檢查。因此,例如測試 (instance? Atom x)
將導致 x
被推斷為 cljs.core/Atom
型別。
在值可能為 nil
(在型別標籤中以符號 clj-nil
表示) 的情況下,如果將引用此值的簡單符號用作條件中的測試,則型別推斷演算法會推斷該值在 then 分支中不能為 nil
。
這或許最好用範例來說明。假設您有以下函式
(defn f [x]
(when (even? x)
(inc x)))
此函式的回傳型別為 #{number clj-nil}
,表示可以回傳數字或 nil
。
以下函式使用 f
,先前會被推斷為回傳 #{number clj-nil}
,現在則被推斷為回傳 number
(defn g [y]
(let [z (f y)]
(if z
z
17)))
事實上,由於 or
巨集的展開方式,現在運算式 (or (f 1) 17)
會被推斷為簡單的 number
。
loop
/ recur
推斷現在,型別推斷演算法會在推斷 loop
區域型別時考慮 recur
參數型別。
例如,在
(loop [x "a"]
(if (= "a" x)
(recur 1)
(+ 3 x)))
先前會將區域變數 x
推斷為字串型別 (這會導致發出將其加到 3
的運算式的警告)。現在,編譯器會將 x
推斷為字串或數字型別 (因此警告將不再出現)。
ClojureScript 1.10.439 新增了函式回傳型別推斷,但此功能僅適用於單參數函式。此版本將此功能擴展到多參數和可變參數函式。
此外,如果不同的參數回傳不同的型別,則推斷的回傳型別會正確變化。例如,
(defn foo
([x] 1)
([x y] "a"))
那麼運算式 (foo true)
會被推斷為數字型別,而 (foo :a :b)
會被推斷為字串型別。
如需 ClojureScript 1.10.516 中更新的完整清單,請參閱 變更。