当前位置:  开发笔记 > 编程语言 > 正文

嵌套在另一个结构中的Clojure结构

如何解决《嵌套在另一个结构中的Clojure结构》经验,为你挑选了3个好方法。

是否可以将结构嵌套在Clojure中的结构中?请考虑以下代码:

(defstruct rect :height :width)
(defstruct color-rect :color (struct rect))

(defn 
#^{:doc "Echoes the details of the rect passed to it"}
echo-rect
[r]
  (println (:color r))
  (println (:height r))
  (println (:width r)))

(def first-rect (struct rect 1 2))
;(def c-rect1 (struct color-rect 249 first-rect)) ;form 1
;output "249 nil nil"
(def c-rect1 (struct color-rect 249 1 2)) ;form 2
;output "Too many arguments to struct constructor

(echo-rect c-rect1)

当然这是一个人为的例子,但有些情况下我想将大型数据结构分解为更小的子结构,以使代码更易于维护.由于注释表明如果我形成1,我得到"249 nil nil",但如果我做表格2,我得到"结构构造函数的参数太多".

如果我以错误的方式处理这个问题,请告诉我应该做什么.搜索Clojure google小组并没有为我提供任何帮助.


编辑:

我想我在问题陈述中并不像我想象的那样清楚:

1.)是否可以在Clojure中将一个结构嵌套在另一个结构中?(从下面判断,这是肯定的.)

2.)如果是这样,那么正确的语法是什么?(同样,从下面看,看起来有几种方法可以做到这一点.)

3.)当你有一个嵌套在另一个结构中的结构时,如何通过指定的键获取值?

我想我的示例代码并没有真正展示我想要做的很好.我在这里添加这个,以便其他人搜索这个可能更容易找到这个问题及其答案.



1> pjb3..:

我同意其他海报的结构图并不真正支持继承.但是,如果您只想创建一个使用另一个键的新结构,这将起作用:

; Create the rect struct
(defstruct rect :height :width)

; Create the color-rect using all the keys from rect, with color added on
(def color-rect (apply create-struct (cons :color (keys (struct rect)))))

(defn create-color-rect 
  "A constructor function that takes a color and a rect, or a color height and width"
  ([c r] (apply struct (concat [color-rect c] (vals r))))
  ([c h w] (struct color-rect c h w)))

您不需要该echo-rect函数,您可以简单地评估struct map实例以查看其中的内容:

user=> (def first-rect (struct rect 1 2))
#'user/first-rect
user=> first-rect
{:height 1, :width 2}
user=> (create-color-rect 249 first-rect)
{:color 249, :height 1, :width 2}
user=> (create-color-rect 249 1 2)
{:color 249, :height 1, :width 2}



2> Nathan Kitch..:

嵌套结构是可能的并且有时是期望的.但是,看起来你正在尝试做一些不同的事情:看起来你正试图使用​​结构类型的继承而不是组合.也就是说,在表单2中,您正在创建一个包含 rect 的color-rect,但是您正在尝试构造一个实例,就好像它一个rect.表单1的工作原理是因为你从一个预先存在的rect构造c-rect1,这是使用组合的正确方法.

快速搜索Clojure组或仅在Web上进行快速搜索可以使您对组合和继承之间的区别进行良好描述.在Clojure中,组合或鸭子打字(再次参见Google)几乎总是优先于继承.


编辑:

回答你的问题#3:使用 - >提取嵌套结构中的数据的替代方法,正如Brian Carper在他的回答中所描述的那样,与其兄弟姐妹关联和更新一起进入:

例如:

(def cr {:rect {:height 1, :width 2}, :color :blue})
(get-in cr [:rect :width])
;; => 2

(assoc-in cr [:rect :height] 7)
;; => {:rect {:height 7, :width 2}, :color :blue}

(update-in cr [:rect :width] * 2)
;; => {:rect {:height 1, :width 4}, :color :blue}

(assoc-in cr [:a :new :deeply :nested :field] 123)
;; => {:a {:new {:deeply {:nested {:field 123}}}}, 
;;     :rect {:height 1, :width 2}, :color :blue}



3> Brian Carper..:

如果给它一个与之关联的键,则可以使struct成为另一个struct的值.你可以这样做.

(您可以通过->一些语法糖轻松访问任意嵌套的哈希/结构的内容.)

(defstruct rect :height :width)
(defstruct color-rect :rect :color)

(def cr (struct color-rect (struct rect 1 2) :blue))
;; => {:rect {:height 1, :width 2}, :color :blue}

(:color cr)           ;; => :blue
(:width (:rect cr))   ;; => 2
(-> cr :color)        ;; => :blue
(-> cr :rect :width)  ;; => 2

推荐阅读
手机用户2402851335
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有