Clojure。在地图中创建带有动态名称关键字的Spec

问题描述 投票:0回答:2

我有这张地图:

{:60 {:id 60, :quote "Lorem ipsum doloret sit anem", :author "foo name", :total 61}
 :72 {:id 72, :quote "Excepteur sint occaecat cupidatat non", :author "Nietzsche", :total 61}
 :56 {:id 56, :quote "Ut enim ad minim veniam, quis nostrud ", :author "O. Wilde", :total 61}
 :58 {:id 58, :quote "Duis aute irure dolor in reprehenderit", :author "your mama", :total 61}}

我正在尝试创建其规格,我想我有地图“内部”:

(s/def ::id     (s/and int? pos?))
(s/def ::quote  (s/and string? #(>= (count %) 8)))
(s/def ::author (s/and string? #(>= (count %) 6)))
(s/def ::total  (s/and int? pos?))

(s/def ::quotes (s/and
             (s/map-of ::id ::quote ::author ::total)
             #(instance? PersistentTreeMap %)             ;; is a sorted-map (not just a map)
            ))

但是map关键字是动态创建的,因此它们没有名称,如何定义这些关键字的规范并将其添加到(s / map-of函数中?

clojure specifications
2个回答
2
投票

map-of采用键谓词,值谓词和可选参数,而不是关键字列表。要定义地图中的关键字列表,可以使用keys函数和:req-un参数,因为您使用的是非限定键。

由于您尚未指定要限制地图关键字的方式,因此我认为它们可以是任何关键字。如果是这种情况,则可以更改以下内容,

(s/def ::key keyword?)

(s/def ::quotes (s/and
                  (s/map-of ::key (s/keys :req-un [::id
                                                   ::quote
                                                   ::author
                                                   ::total]))
                  #(instance? clojure.lang.PersistentTreeMap %)))

使用上面的示例图,我们可以看到此规范定义相对应。

user=> (s/valid? ::quotes 
   #=>           (into (sorted-map)
   #=>                 {:60 {:id     60
   #=>                       :quote  "Lorem ipsum doloret sit anem"
   #=>                       :author "foo name"
   #=>                       :total  61}
   #=>                  :72 {:id     72
   #=>                       :quote  "Excepteur sint occaecat cupidatat non"
   #=>                       :author "Nietzsche"
   #=>                       :total  61}
   #=>                  :56 {:id     56
   #=>                       :quote  "Ut enim ad minim veniam, quis nostrud "
   #=>                       :author "O. Wilde"
   #=>                       :total  61}
   #=>                  :58 {:id     58
   #=>                       :quote  "Duis aute irure dolor in reprehenderit"
   #=>                       :author "your mama"
   #=>                       :total  61}}))
true

3
投票

只需使用整数作为映射键。关键字化任意字符串是通常错误;关键字数字化是一种特别清晰的反模式。那么规范很简单:它只是一个带有int键的映射。

© www.soinside.com 2019 - 2024. All rights reserved.