gpt4 book ai didi

clojure - 如何在 Clojure 和 ClojureScript 之间共享协议(protocol)

转载 作者:行者123 更新时间:2023-12-02 16:46:24 25 4
gpt4 key购买 nike

我在交叉命名空间中有一个协议(protocol):

(ns xxx.shared.interfaces)

(defprotocol ITimer
(seconds [timer] "Return time in seconds since timer began"))

我有一个 Clojure 的实现:

(ns xxx.time
(:require [xxx.shared.interfaces :refer [ITimer]]))

(defrecord Timer [start-nanos]
ITimer
(seconds [timer] (double (/ (- (System/nanoTime) (:start-nanos timer))
1000000000))))

问题是,当我在某些 Clojure 代码中使用此代码时,需要使用 :refer :allxxx.time 命名空间,它提示找不到:

Unable to resolve symbol: seconds in this context

首先,是否可以通过这种方式共享协议(protocol)?

其次,知道我如何才能完成这项工作吗?

第三,这实际上是进行这种代码共享的好方法吗?理想情况下,我也想共享该记录,但它依赖于 Java 代码,因此我需要将其分解为一个函数。这是解决这个问题的更好方法吗?

谢谢!

最佳答案

seconds 是在 xxx.shared.interfaces 中定义的,因此这就是您需要 :require/:use 能够调用它:

(ns foo
(:require [xxx.shared.interfaces :refer [seconds]]))

;; (seconds ...) will now work

详细来说,defprotocol 表达式创建一个保存协议(protocol)的 Var、JVM 端的底层 JVM 接口(interface)(ClojureScript 端没有与之对应的接口(interface))以及每个协议(protocol)方法的 Var 。然后可以像任何其他 Clojure 函数一样通过这些 Var 调用协议(protocol)方法。

当您为记录/类型实现协议(protocol)时,就像在 xxx.time 命名空间中所做的那样,如果您实际上不调用方法(与提供实现不同的问题)。类似地,需要调用协议(protocol)方法但不太关心调用它们的特定对象类型的命名空间,只需要引入协议(protocol)定义命名空间并使用相关的 Var,而无需:require 任何实现命名空间。

关于clojure - 如何在 Clojure 和 ClojureScript 之间共享协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18526439/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com