无法获取宏的值:#'clojure.core / case

时间:2019-02-22 19:22:38

标签: clojure

我正在Clojure中的函数内创建一个函数,以模拟Java的对象概念,其中我的函数人像构造函数一样工作。 (只需要在Clojure中使用这个概念就行了。)

import { Field, Abc } from 'react-final-form-html5-validation'
// correct: Module '"react-final-form-html5-validation"' has no exported member 'Abc'

// later in App.render() { return ( .....
      <Field />

// Field is of type React.ComponentType<any>

但是出现以下错误:

CompilerException java.lang.RuntimeException:无法获取宏的值:#'clojure.core / case,编译:(null:2:8)

1 个答案:

答案 0 :(得分:0)

  1. 您(几乎总是)不应在另一个defdef中使用defn。使用def是一个全局声明,它应该(几乎)在源文件中始终独立存在。

请参阅Clojure for the Brave & True以获得在线介绍,或阅读Getting Clojure之类的好书。

  1. 您忘记了case周围的括号:

示例:

(case args ...)
  1. 使用case实际上是一个专门为Java对象互操作设计的特殊功能,并且存在一些严重的局限性(即“优化”)。恕我直言,使用cond几乎总是更好。

示例:

(cond
  (= :set-name args)   (person (first args) age)
  (= :set-age  args)   (person age)
  ...)

更新

case的问题之一是它必须为a compile-time literal。但是,这并不明显,如果您尝试使用不符合定义的内容,也不会发出警告。然后,您只会遇到无声的失败。此示例看起来应该返回"my vec",但失败并返回"default"

; "The test-constants are not evaluated.  They must be compile-time
; literals, and need not be quoted." 
(let [myvec [1 2]]
  (case myvec
    []             "empty vec"
    (vec '(1 2))   "my vec"
    "default"))
;=> "default"

因此,使用case会留下一个诱骗陷阱,可以在不发出警告的情况下破坏代码。