Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.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 - Fatal编程技术网

Clojure 为什么这个异常没有被捕获?

Clojure 为什么这个异常没有被捕获?,clojure,Clojure,如果我定义以下函数 (defn catcher [x] (try (load-string x) (catch Exception e (prn "caught"))) ) (catcher“(+2\'2\”)=>“捕获” 但是,(catcher)(键[12])”=>ClassCastException java.lang.Long不能转换为java.util.Map$Entry 通常这两个输入都会抛出ClassCastException,那么为什么只捕获第

如果我定义以下函数

(defn catcher [x] (try 
    (load-string x)
    (catch Exception e 
        (prn "caught"))) )
(catcher“(+2\'2\”)
=>“捕获”

但是,
(catcher)(键[12])”
=>ClassCastException java.lang.Long不能转换为java.util.Map$Entry


通常这两个输入都会抛出ClassCastException,那么为什么只捕获第一个呢?

在尝试打印
(键[1 2])的结果时,似乎发生了异常。

在这里,您可以看到表达式实际上正在创建/返回一个
KeySeq
,而没有抛出/捕获异常。只有当打印了
KeySeq
时,才会引发异常:

java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Map$Entry
    at clojure.lang.APersistentMap$KeySeq.first(APersistentMap.java:168)
    at clojure.lang.RT.first(RT.java:685)
    at clojure.core$first__5107.invokeStatic(core.clj:55)
    at clojure.core$print_sequential.invokeStatic(core_print.clj:64)
    at clojure.core$fn__7021.invokeStatic(core_print.clj:174)
    at clojure.core$fn__7021.invoke(core_print.clj:174)
    at clojure.lang.MultiFn.invoke(MultiFn.java:233)
    at clojure.tools.nrepl.middleware.pr_values$pr_values$fn$reify__784.send(pr_values.clj:35)

请注意,在堆栈跟踪中,当REPL尝试实现打印序列时,此异常源自
KeySeq.first
方法(在函数创建并返回其值后才会调用该方法)。

请注意,
[1 2]
,当您键入它时,它是一个clojure
向量,不是Clojure
MapEntry
。请参见以下结果:

(ns tst.demo.core
  (:use tupelo.test)
  (:require
    [tupelo.core :as t] ) )
(t/refer-tupelo)

(dotest
  (newline)
  (let [my-map      {:a 1 :b 2}
        map-entries (vec my-map)
        map-entry-1 (first map-entries)
        map-keys    (keys my-map)
        entry-1-key (key map-entry-1)
  ]
    (is= map-entries [[:a 1] [:b 2]] )
    (is= map-entry-1 [:a 1] )
    (is= map-keys [:a :b])
    (is= entry-1-key :a)

    (spyxx my-map)
    (spyxx map-entries)
    (spyxx map-entry-1)
    (spyxx map-keys)
    (spyxx entry-1-key)
  ))
结果如下:

Testing tst.demo.core

my-map        => <#clojure.lang.PersistentArrayMap {:a 1, :b 2}>
map-entries   => <#clojure.lang.PersistentVector [[:a 1] [:b 2]]>
map-entry-1   => <#clojure.lang.MapEntry [:a 1]>
map-keys      => <#clojure.lang.APersistentMap$KeySeq (:a :b)>
entry-1-key   => <#clojure.lang.Keyword :a>

Ran 2 tests containing 4 assertions.
0 failures, 0 errors.
然而,它们是不同的类型。当您执行
(加载字符串“[1 2]”
时,它返回的是向量,而不是映射,因此您无法调用
函数


第二部分 在你最初的问题中,你问了

(catcher "(keys [1 2])") => Exception

我怀疑
load string
正在返回一个延迟结果,这在您的代码退出try catch块之前是无法实现的,这就是为什么无法捕获异常。

出于好奇,您为什么还要使用
load string
?看起来如果你把它做成一个宏,你就可以把它简化一点。我想要一个try/catch的测试平台,但我还不习惯使用宏。你仍然会使用try/catch。它看起来像是
(defmacro catcher[body]`(try~@body catch Exception e(prn“catch”))
(显然,您可以用双反勾号包围代码,以在注释中转义单反勾号)。@Carcigenicate+1表示双反勾号trick@madstap哎,,我很高兴在我的编辑期结束之前就发现了这个问题。我本来打算在Meta上做一个自我问答,但是已经有一篇文章描述了它。
`[1 2]`
(catcher "(keys [1 2])") => Exception