使用clojure.core.match时“不能让限定名称”

时间:2014-02-25 10:50:24

标签: clojure pattern-matching clojure-core.match

我正在使用clojure.core.match并看到以下错误:

  

不能让限定名称

我的代码类似于:

(match [msg-type]
       [MsgType/TYPE_1] (do-type-1-thing)
       [MsgType/TYPE_2] (do-type-2-thing))

MsgType/TYPE_1来自Java类:

public class MsgType {
    public static final String TYPE_1 = "1";
    public static final String TYPE_2 = "2";
}

这个错误是什么意思,我该如何解决它?

2 个答案:

答案 0 :(得分:1)

问题似乎related to macro name binding,虽然我不太了解它,因为我对宏很新。

最初,我希望使用case而非match证明是可行的解决方法:

(case msg-type
      MsgType/TYPE_1 (do-type-1-thing)
      MsgType/TYPE_2 (do-type-2-thing))

但是上述方法不起作用。 case匹配符号MsgType/TYPE_n,而不是该符号的评估。

到目前为止,我发现的最好的方法是将输入的值转换为关键字并按照这种方式匹配:

(def type->keyword
     {MsgType/TYPE_1 :type-1
      MsgType/TYPE_2 :type-2})

(case (type->keyword msg-type)
      :type-1 (do-type-1-thing)
      :type-2 (do-type-2-thing))

答案 1 :(得分:1)

通常,模式匹配不是将一个变量与另一个变量进行比较的正确工具。模式应该是文字,例如1:a,解构表达式或要绑定的变量。因此,例如,请使用以下表达式:

(let [a 1
      b 2]
  (match [2]
    [a] "It matched A"
    [b] "It matched B"))

你可能期望它产生“它匹配B”,因为变量b等于2,但实际上它会将值2绑定到一个名为a的新变量并产生“它匹配A“。

我认为你正在寻找condp =。这基本上就是你想要的case

(condp = msg-type
  MsgType/TYPE_1 (do-type-1-thing)
  MsgType/TYPE_2 (do-type-2-thing))