Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 以原子为单位增加一个值_Clojure_Clojurescript - Fatal编程技术网

Clojure 以原子为单位增加一个值

Clojure 以原子为单位增加一个值,clojure,clojurescript,Clojure,Clojurescript,我正在学习clojurescript,我偶然发现了这个片段 :on-click (fn [] (swap! state/order update (:id gig) inc)) 我在文档中查找了update函数,它说update包含一个键和一个函数。将旧值从原子传递给函数,然后更新原子。如果atom中没有键的现有值,则将nil作为输入传递给函数。 当我在repl中尝试同样的方法时,它不起作用 (def atom-test (atom {})) (swap! atom-test update :

我正在学习clojurescript,我偶然发现了这个片段

:on-click (fn [] (swap! state/order update (:id gig) inc))
我在文档中查找了
update
函数,它说update包含一个键和一个函数。将旧值从原子传递给函数,然后更新原子。如果atom中没有键的现有值,则将nil作为输入传递给函数。 当我在repl中尝试同样的方法时,它不起作用

(def atom-test (atom {}))
(swap! atom-test update :aa inc)
NullPointerException   clojure.lang.Numbers.ops (Numbers.java:1013)
添加
fnil
以捕获此NullPointerException有效

user=> (swap! atom-test update :aa (fnil inc 0))
{:aa 1}

我无法理解为什么它在clojurescript的案例1中有效,为什么它在clojure repl的案例2中无效。谁能解释一下这里的诀窍是什么。

对于cljs,操作通常安全地处理nil而不引起异常

cljs.user=> (update {} :a inc)
{:a 1}
cljs.user=> (inc nil)
1
cljs.user=> (+ 1 nil)
1

函数的
inc
需要满足
number?
的参数。这在Clojure和ClojureScript中是正确的

如果您传递了其他内容,如
nil
,则程序不正确:
(inc nil)
具有未定义的行为。这样做不安全。它恰好返回
1
,但这不能保证,这是一个意外的实现

例如,如果将文本字符串传递给
inc
,ClojureScript将在编译时发出警告:

cljs.user=> (inc "a")
WARNING: cljs.core/+, all arguments must be numbers, got [string number] instead at line 1 <cljs repl>
cljs.user=>(包括“a”)
警告:cljs.core/+,所有参数都必须是数字,在第1行获得[string number]
也许在将来,编译器也会发出类似的警告,警告
(inc nil)
,但更可能发生的是,编写的规范将涵盖核心函数,并指定
cljs.core/inc
接受满足
number?
的参数


TL;DR:在这里使用
fnil
是正确的做法。

同样的原因,您可以在浏览器控制台中输入
1+null
,以获得
1
,而不会出现错误。我会在两边使用
fnil
,我认为Clojure和ClojureScript的功能类似。