gpt4 book ai didi

clojure - 将 defmulti 转换为 defprotocol

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

是否可以转换以下代码,使其使用 defprotocoldefrecord 而不是 defmultidefmethod

(defmulti test-multimethod (fn [keyword] keyword))

(defmethod test-multimethod :foo [a-map]
"foo-method was called")

(defmethod test-multimethod :bar [a-map]
"bar-method was called")

(defmulti perimeter (fn [shape] (:shape-name shape)))
(defmethod perimeter :circle [circle]
(* 2 Math/PI (:radius circle)))
(defmethod perimeter :rectangle [rectangle]
(+ (* 2 (:width rectangle)) (* 2 (:height rectangle))))

(def some-shapes [{:shape-name :circle :radius 4}
{:shape-name :rectangle :width 2 :height 2}])

(defmulti area (fn [shape] (:shape-name shape)))
(defmethod area :circle [circle]
(* Math/PI (:radius circle) (:radius circle)))
(defmethod area :rectangle [rectangle]
(* (:width rectangle) (:height rectangle)))

(defmethod perimeter :square [square]
(* 4 (:side square)))
(defmethod area :square [square]
(* (:side square) (:side square)))

(def more-shapes (conj some-shapes
{:shape-name :square :side 4}))


(for [shape more-shapes] (perimeter shape))
(for [shape more-shapes] (area shape))

最佳答案

是的,你在协议(protocol)定义Shape中声明你的函数,然后你在你的各种记录实现中定义你的实现SquareCircle

(defprotocol Shape 
(area [this])
(perimeter [this]))

(defrecord Square [side] Shape
(area [this] (* (:side this) (:side this)))
(perimeter [this] (* 4 (:side this))))

(defrecord Rect [w l] Shape
(area [this] (* (:l this) (:w this)))
(perimeter [this] (+ (:l this) (:l this) (:w this) (:w this))))

(def s (->Square 4))
(def r (->Rect 2 5))

(map area [s r]) ; '(16 10)
(map :side [s r]) ; '(4 nil)
(map :l [s r]) ; '(nil 5)

本质上这就像 OOP(但不可变),如果您熟悉的话。

尽管如此,关于 defmulti 实现的一个好处是,您通常可以序列化和反序列化您的 map 并按原样使用它们,而不必将它们具体化为特定的记录类。

关于clojure - 将 defmulti 转换为 defprotocol,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30252614/

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