【问题标题】:What's wrong with this use of rest params with defprotocol and defrecord in Clojure?在 Clojure 中使用带有 defprotocol 和 defrecord 的 rest 参数有什么问题?
【发布时间】:2011-11-14 17:50:05
【问题描述】:

下面在 Clojure 中使用带有 defprotocol 和 defrecord 的 rest 参数有什么问题?

(defprotocol prot
  (f [this] [this & rest]))

(defrecord rec []
  prot
  (f [this] "one arg")
  (f [this & rest] "more than one arg"))

(prn (f (rec.)))
; (prn (f (rec.) 5))
(prn (f (rec.) 5 6))
; (prn (f (rec.) 5 6 7))

上面的代码打印出我期望的输出:

"one arg"
"more than one arg"

但是,如果我取消注释任何一条注释行,我会得到以下异常:

Exception in thread "main" java.lang.IllegalArgumentException: No single method: f of interface: user.prot found for function: f of protocol: prot (bug.clj:10)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5376)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyze(Compiler.java:5151)
    at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3057)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5371)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.analyze(Compiler.java:5151)
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:4670)
    at clojure.lang.Compiler$FnMethod.parse(Compiler.java:4328)
    at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3173)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5367)
    at clojure.lang.Compiler.analyze(Compiler.java:5190)
    at clojure.lang.Compiler.eval(Compiler.java:5421)
    at clojure.lang.Compiler.load(Compiler.java:5857)
    at clojure.lang.RT.loadResourceScript(RT.java:340)
    at clojure.lang.RT.loadResourceScript(RT.java:327)
    at clojure.lang.RT.loadResourceScript(RT.java:319)
    at clojure.main$load_script.invoke(main.clj:220)
    at clojure.main$script_opt.invoke(main.clj:273)
    at clojure.main$main.doInvoke(main.clj:354)
    at clojure.lang.RestFn.invoke(RestFn.java:409)
    at clojure.lang.Var.invoke(Var.java:365)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:482)
    at clojure.main.main(main.java:37)
Caused by: java.lang.IllegalArgumentException: No single method: f of interface: user.prot found for function: f of protocol: prot
    at clojure.lang.Compiler$InvokeExpr.<init>(Compiler.java:2880)
    at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3063)
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5371)
    ... 24 more

这是为什么?

【问题讨论】:

标签: clojure variadic-functions


【解决方案1】:

据我所知,协议不支持可变参数。可能发生的情况是“&”被视为参数符号而不是可变参数指示符/列表理解。

【讨论】:

  • 你是对的。多么令人沮丧!如果是这样的话,我一定是误解了协议的预期用途。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-13
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多