请在 2024 Clojure状态调查! 分享您的想法。

欢迎!有关此功能的更多信息,请参阅 关于 页面。

0
ClojureScript

在CLJS中构建自定义比较函数时,我遇到了一些我认为很奇怪的行为

直接在REPL中使用 >(或类似的)函数对两个字符串进行比较时,我会收到一个 :invalid-arithmetic 警告,并返回 nil(与CLJ引发异常类似)。如果我这样做,它将返回一个布尔值而没有任何警告(CLJ引发异常)

CLJS

clj꞉user꞉> (> "A" "Z")
nil
; ------ WARNING - :invalid-arithmetic -------------------------------------------
;  Resource: <eval>:1:1
 cljs.core/>, all arguments must be numbers, got [string string] instead
--------------------------------------------------------------------------------

clj꞉user꞉> ((fn [x y] (> x y)) "A" "Z")
false

CLJ

user=> (> "A" "Z")
Execution error (ClassCastException) at user/eval3 (REPL:1).
class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')
user=> ((fn [x y] (> x y)) "A" "Z")
Execution error (ClassCastException) at user/eval5$fn (REPL:1).
class java.lang.String cannot be cast to class java.lang.Number (java.lang.String and java.lang.Number are in module java.base of loader 'bootstrap')

有人能解释发生了什么吗?

谢谢,
Julian

1 答案

+2

被选中
 
最佳答案

警告 - :invalid-arithmetic 来自运行在代码编译期间的 CLJS 分析器。当它能够确定参数的类型并且这些类型不是数字时,它会发出警告。当它不能确定,就像函数示例那样,它将保持沉默。

并且它不会导致运行时错误,因为底层平台JavaScript允许这样做。但您仍然应该使用ClojureScript的>,因为它本意上是作为一种算术操作。

在CLJ中,底层平台JVM不支持在字符串上使用>,这就是为什么这始终是一个错误。

谢谢你的快速回答,Eugene!说得通,但这能解释为什么评估表达式`(> "A" "B")` 返回nil吗?我想这并不很重要,但看起来不太一致。我同意对于不是数字类型的操作,即使它在JavaScript运行时上工作,也不应使用>等。

I
我认为这是因为除了数字类型以外的任何东西上使用`>`是一种未定义的行为。哦,并且在我的情况下,它在我基于Node的REPL中返回预期的布尔值。
...