(if (string? x)
(inc x)
10)
2019 年 1 月 31 日
ClojureScript 团队
Spec 检测 (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.edn/read
和 clojure.edn/read-string
的可移植 Clojure/ClojureScript 源代码。
类型推断算法现在将考虑核心谓词,以便推断条件表达式中使用的局部变量的类型。
例如,在
(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
推断类型推断算法现在将考虑 recur
参数类型,以便推断 loop
局部变量类型。
例如,在
(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 中所有更新的完整列表,请参阅 变更。