3

这是重载协议定义的一部分:

(defprotocol ClientProtocol
  (create-edge
    [this outV label inV] 
    [this outV label inV data])

这是其实现的一部分:

(ns bulbs.neo4jserver.client
  (:use [bulbs.base.client :only [ClientProtocol]]))

(deftype Neo4jClient [ns config]
  ClientProtocol

  (create-edge
    [this outV label inV data]
    (let [inV-uri (utils/normalize-uri (build-path neo4j-uri vertex-path inV))
          path (build-path vertex-path, outV, "relationships")
          params {:to inV-uri, :type label, :data (first data)}]
      (post config path params)))

  (create-edge
    [this outV label inV]
    ;; it doesn't like this call...
    (create-edge this outV label inV nil)) 

当第二种方法尝试调用第一种方法时,它会发出此错误:

java.lang.RuntimeException: Unable to resolve symbol: create-edge in this context

当我使用第一个函数编译它然后返回并添加第二个函数时,我在 SLIME 中的两个定义都在早期工作。

但是当我将协议定义移动到一个单独的文件中并尝试重新编译整个东西时,当第二种方法尝试调用第一种方法时,它会引发错误,大概是因为第一种方法尚未定义。

Clojurereify文档有这样的评论:

如果一个方法在协议/接口中被重载,则必须提供多个独立的方法定义。

http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/reify

我想这些不是独立的定义。

解决这个问题的正确方法是什么?

4

3 回答 3

3

您的命名空间声明是错误的。

(ns bulbs.neo4jserver.client
  (:use [bulbs.base.client :only [ClientProtocol]]))

协议函数是普通的 Clojure 函数,必须这样处理。因此,您必须将它们包含在您的:only条款中。

(ns bulbs.neo4jserver.client
  (:use [bulbs.base.client :only [create-edge ClientProtocol]]))
于 2012-05-21T06:15:12.367 回答
2

这是一个适用于 clojure 1.4.0 的简化示例

(ns hello.core)
(defprotocol ClientProtocol
 (create-edge
    [this outV label inV] 
    [this outV label inV data]))

(deftype Neo4jClient []
  ClientProtocol

 (create-edge
   [this outV label inV data]
    4)

  (create-edge
    [this outV label inV]
    (create-edge this outV label inV nil)))

hello.core> (create-edge (Neo4jClient.) 2 3 4)
4

hello.core> (create-edge (Neo4jClient.) 2 3 4 5)
4

这是一个相互递归的例子(没有基本情况)

(deftype Neo4jClient []
  ClientProtocol

  (create-edge
    [this outV label inV data]
    (println "OMG im in a looooooop...")
    (create-edge this 1 2 3))

  (create-edge
    [this outV label inV]
    (println "AHHH im in a looooooop...")
    (create-edge this 1 2 3 4)))


hello.core> (create-edge (Neo4jClient.) 1 2 3 4)
OMG im in a looooooop...
AHHH im in a looooooop...
OMG im in a looooooop...
AHHH im in a looooooop...
OMG im in a looooooop...
AHHH im in a looooooop...
OMG im in a looooooop...
AHHH im in a looooooop...
于 2012-05-18T00:38:42.980 回答
0

你在这里做什么工作正常。

考虑这个例子:

(defprotocol ClientProtocol
  (create-edge
    [this outV label inV]
    [this outV label inV data]))

(deftype SampleClient []
  ClientProtocol

  (create-edge
    [this outV label inV]
      (create-edge this outV label inV {}))

  (create-edge
    [this outV label inV data]
      {:action :create-edge :this this :outV outV :label label :inV inV :data data}))

运行时的行为符合预期:

; => (create-edge (SampleClient.) 1 2 3)
{:action :create-edge, :this #<SampleClient user.SampleClient@63a2cc03>,
 :outV 1, :label 2, :inV 3, :data {}}
; => (create-edge (SampleClient.) 1 2 3 4)
{:action :create-edge, :this #<SampleClient user.SampleClient@7144c1a4>,
 :outV 1, :label 2, :inV 3, :data 4}
于 2012-05-18T18:59:47.063 回答