Clojure 函数中相当于 Java 的 toString()

发布于 2024-10-21 19:58:00 字数 227 浏览 5 评论 0原文

我使用的一些 Java 代码在 Clojure 函数对象上调用 toString() ,该对象返回类似 #>- 我想返回其他东西...大概有一种方法可以在函数中包含一些元数据,以便它们的对象的 toString() 返回它?

some Java code I'm using invokes toString() on my Clojure function objects, which return something like #<ns$something something.something$something@7ce1eae7>>- I want to return something else...presumably there's a way to include some metadata in the functions so their objects' toString() returns that instead ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

放我走吧 2024-10-28 19:58:01

如果您只是想让对象的 REPL 打印输出更有意义,您可以为相关类实现一个 defmethod print-method

这是我最近编写的一些代码的简化版本;这使得 Selenium-WebDriver WebDriver 对象的 REPL 打印输出更有意义:

(defmethod print-method WebDriver
[o w]
(print-simple
 (str "#<" "Title: "    (.getTitle o) ", "
           "URL: "      (.getCurrentUrl o) " >")
  w))

这打印出来像 #

这里,< code>WebDriver 代表一个类;您可以通过为适当的类实现 print-method 来轻松地对内置 Clojure 数据结构执行此操作(The Joy of Clojure features a print-method for clojure.lang.PersistentQueue 默认情况下没有很好的表示)。上面的 o 是您正在处理的实际对象,而 w 是一个编写器(这些类型的打印函数需要)。

If you just want to make the REPL print-out of your objects more meaningful, you can implement a defmethod print-method for the class in question.

Here's a shortened version of some code I've written recently; this makes the REPL print-out of a Selenium-WebDriver WebDriver object more meaningful:

(defmethod print-method WebDriver
[o w]
(print-simple
 (str "#<" "Title: "    (.getTitle o) ", "
           "URL: "      (.getCurrentUrl o) " >")
  w))

This prints out like #<Title: A Title, URL: http://example.com >

Here, WebDriver represents a class; you can just as easily do this for built-in Clojure data structures by implementing print-method for the appropriate class (The Joy of Clojure features a print-method for clojure.lang.PersistentQueue which has no nice representation by default). The o above is the actual object you're dealing with and w is a writer (required by these kinds of print functions).

死开点丶别碍眼 2024-10-28 19:58:01

AFAIK,没有简单的方法可以做到这一点,尽管您可以使用 reify 或 proxy 来实现 clojure.lang.IFn - 这实际上只是将您的函数对象包装在另一个对象中。

(def my-fn
  (let [f (fn [a] (println a))] 
     (reify clojure.lang.IFn
        (toString [this] "bla")
        (invoke [this a] (f a)))))


#'user/my-fn
user> my-fn
#<user$fn$reify__2903 bla>
user> (my-fn 2)
2
nil
user> (.toString my-fn)
"bla"
user> (str my-fn)
"bla"

AFAIK, there's no simple way of doing this, though you can use reify or proxy to implement clojure.lang.IFn - which really just amounts to wrapping your function object in another object.

(def my-fn
  (let [f (fn [a] (println a))] 
     (reify clojure.lang.IFn
        (toString [this] "bla")
        (invoke [this a] (f a)))))


#'user/my-fn
user> my-fn
#<user$fn$reify__2903 bla>
user> (my-fn 2)
2
nil
user> (.toString my-fn)
"bla"
user> (str my-fn)
"bla"
往日情怀 2024-10-28 19:58:01

我认为对此您无能为力:如果不深入研究并重新设计 Clojure 的内部结构,就无法确保您的函数以不同的方式实现 toString() 。

不过我认为你可以很容易地解决这个问题 - 我建议将你的函数包装在你控制的另一个类中(例如通过 defrecord),然后再传递给 Java 代码 - 然后您将能够提供自己的自定义 toString() 方法,并获得使用记录的所有其他优点。

I don't think there's anything you can do about this: there's no way to ensure that your functions implement toString() differently without diving in and re-engineering the internals of Clojure.

However I think you can work around this problem quite easily - I'd suggest wrapping your functions within another class that you control (e.g. as defined through defrecord) before passing to Java code - then you will be able to provide your own custom toString() method, as well as get all the other advantages of using a record.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文