gpt4 book ai didi

clojure - 如何使用 Clojure 代理制作类 java 类?

转载 作者:行者123 更新时间:2023-12-01 01:11:10 25 4
gpt4 key购买 nike

我想在 Clojure 中创建一个具有属性和方法的对象,我读到 gen-class 和 proxy 可以完成我需要的工作,但它的实现对我来说非常困惑。

我想使用代理来避免 AOT 编译步骤,我阅读了它,但我最好学习如何使用两者中更容易的一个

这是我想在 Clojure 中做的事情

Java代码:

public class MyClass {
public float myFloat;

MyClass( float _myFloat ) {
myFloat = _myFloat
}

public void showNumber() {
println( myFloat );
}
}

我正在努力使用代理将该代码转换为 Clojure,任何帮助将不胜感激

更新:

显然 默认类型 更适合我的目的,但我仍在努力实现它

这是我的 Clojure 代码:
(deftype Particle [x y]
Object
(render [this]
(no-stroke)
(fill 200 30 180)
(ellipse x y 200 200)))

事情是我需要指定一个我不确定要使用哪个协议(protocol)的协议(protocol),所以我正在使用 Object ,因为我正在尝试创建一个类似 java 的对象,但我收到以下错误消息:

无法在接口(interface)中定义方法:render

如果有帮助,我正在使用 quill,它是 Clojure 的处理端口

更新 2:

好的,我设法获得了一个有效的 defprotocol 和 deftype 组合,但是我还需要学习如何做一件事,那就是向我的类添加成员变量或属性,这是我的 clojure 代码:
(defprotocol ParticleProtocol
(update [this])
(render [this]))

(deftype Particle [position]
ParticleProtocol
(update [this])
(render [this]
(no-stroke)
(fill 200 30 180)
(ellipse (.x position) (.y position) 20 20)))

对于这个对象,我想添加几个变量,比如半径等,有什么想法吗?

最佳答案

我同意 deftype (或可能 defrecord )优于 proxy在 Clojure 中执行此操作,但请参阅最后的评论以考虑所有可能性。

对于更新 2 之后的问题。

您可以通过在 arglist 中指定它们来将“属性”添加到记录:

(deftype Particle [position radius prop3 prop4]
...
)

请记住,Clojure 中的类型是不可变的,因此没有在创建实体后设置属性的概念。如果某些属性是可选的,建议最佳做法是创建辅助“工厂”方法,例如:

(defn make-particle 
([position] (Particle. position nil nil nil))
([position radius] (Particle. position radius nil nil))
;; etc. add more here as needed
)

要考虑的一个选项是完全删除类型并仅使用映射,其中包含您需要的任何“属性/字段”。当您需要实现抽象时,类型很有用。对于您的 ParticleProtocol - 它提供的值(value)是什么?协议(protocol)旨在提供一种具有多态性的方法,那么您会有该协议(protocol)的多个实现吗?

Chas Emerick 做了一个关于如何在 Clojure 中选择数据类型的深入流程图,可能会对您有所帮助: http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/

[更新显示示例 map 实现] :

要使用“属性”构建 map 并检索该属性,您将执行以下操作:

(def mymap {:myfloat 3.1415926})
(println "myfloat has value:" (:myfloat mymap))

要提供附加功能,例如“渲染”功能,只需创建一个接受带有所需键的映射的 fn:

;; the details are bogus, just showing the syntax
(defn render [m]
(no-stroke)
(fill (:radius m) (:position m))
(do-something-else (:position m)))

为您的 update ,如果您打算更新粒子贴图中的值,那么您需要创建一个新贴图,而不是更新现有贴图。

(def myparticle {:position 100 :radius 25})

(defn change-pos [particle-map new-pos]
(assoc-in particle-map [:position] new-pos))

(let [new-particle (change-pos myparticle 300)]
(println new-particle))
;; prints out {:position 300 :radius 25}
;; orig myparticle still has value {:position 100 :radius 25}

;; or do it directly
(println (assoc myparticle :position 300))
;; prints out {:position 300 :radius 25}

关于clojure - 如何使用 Clojure 代理制作类 java 类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15459877/

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