clojure.spec 中的禁用键
Forbidden keys in clojure.spec
我正在关注clojure.spec guide。我知道在使用 clojure 时可以声明必需属性和可选属性。spec/keys.
我不明白可选的是什么意思。对我来说 :opt 什么都不做。
(s/valid? (s/keys :req [:my/a]) {:my/a 1 :my/b 2}) ;=> true
(s/valid? (s/keys :req [:my/a] :opt []) {:my/a 1 :my/b 2}) ;=> true
向导答应向我解释这个,"We’ll see later where optional attributes can be useful",但我没有找到解释。我可以声明禁用密钥吗?或者以某种方式声明有效密钥集等于 :req 和 :opt?
中的密钥
这是一个很好的问题,clojure.spec API 给出了(理所当然的、简短的、不令人满意的)答案:
The :opt keys serve as documentation and
may be used by the generator.
我认为如果地图包含额外的(我认为这就是您所说的 "forbidden" 键),则您无法使用此方法使地图无效。但是,您可以使用此规范来确保 ::bad-key 不存在:
(s/def ::m (s/and (s/keys :req [::a]) #(not (contains? % ::bad-key))))
(s/valid? ::m {::a "required!"}) ; => true
(s/valid? ::m {::a "required!" ::b "optional!"}) ; => true
(s/valid? ::m {::a "required!" ::bad-key "no good!"}) ; => false
您可以使用此规范将键的数量限制为您想要的数量:
(s/def ::r (s/and (s/keys :req [::reqd1 ::reqd2]) #(= (count %) 2)))
(s/valid? ::r {::reqd1 "abc" ::reqd2 "xyz"}) ; => true
(s/valid? ::r {::reqd1 "abc" ::reqd2 "xyz" ::extra 123}) ; => false
不过,处理此 IMO 的最佳方法是简单地忽略存在您不关心的密钥。
希望随着规范的成熟,这些好东西会被添加进来。或者,也许它们已经存在(变化很快)而我根本不知道。这是 clojure 中一个非常新的概念,所以我们大多数人都需要学习很多东西。
更新 - 2016 年 12 月
我只是想在写完这 6 个月后重温一下。看起来我最初关于忽略您不关心的键的评论是首选方法。事实上,在我两周前参加的 clojure/conj 会议上,Rich 的主题演讲专门讨论了软件所有级别(从功能级别到应用程序级别)的版本控制概念。他甚至在演讲中特别提到了禁止按键的概念,可以在 on youtube 中找到。他说它是有意设计的,因此只能指定必需的键。不允许密钥确实没有任何好处,应该谨慎行事。
关于 :opt
键,我认为原始答案仍然站得住脚——它是文档,实际上,它允许生成这些可选指定的键:
(s/def ::name #{"Bob" "Josh" "Mary" "Susan"})
(s/def ::height-inches (s/int-in 48 90))
(s/def ::person (s/keys :req-un [::name] :opt-un [::height-inches]))
(map first (s/exercise ::person))
; some generated data have :height-inches, some do not
({:name "Susan"}
{:name "Mary", :height-inches 48}
{:name "Bob", :height-inches 49}
{:name "Josh"}
关于可选键的要点是 值 如果它们出现在映射
中则将被验证
我正在关注clojure.spec guide。我知道在使用 clojure 时可以声明必需属性和可选属性。spec/keys.
我不明白可选的是什么意思。对我来说 :opt 什么都不做。
(s/valid? (s/keys :req [:my/a]) {:my/a 1 :my/b 2}) ;=> true
(s/valid? (s/keys :req [:my/a] :opt []) {:my/a 1 :my/b 2}) ;=> true
向导答应向我解释这个,"We’ll see later where optional attributes can be useful",但我没有找到解释。我可以声明禁用密钥吗?或者以某种方式声明有效密钥集等于 :req 和 :opt?
中的密钥这是一个很好的问题,clojure.spec API 给出了(理所当然的、简短的、不令人满意的)答案:
The :opt keys serve as documentation and may be used by the generator.
我认为如果地图包含额外的(我认为这就是您所说的 "forbidden" 键),则您无法使用此方法使地图无效。但是,您可以使用此规范来确保 ::bad-key 不存在:
(s/def ::m (s/and (s/keys :req [::a]) #(not (contains? % ::bad-key))))
(s/valid? ::m {::a "required!"}) ; => true
(s/valid? ::m {::a "required!" ::b "optional!"}) ; => true
(s/valid? ::m {::a "required!" ::bad-key "no good!"}) ; => false
您可以使用此规范将键的数量限制为您想要的数量:
(s/def ::r (s/and (s/keys :req [::reqd1 ::reqd2]) #(= (count %) 2)))
(s/valid? ::r {::reqd1 "abc" ::reqd2 "xyz"}) ; => true
(s/valid? ::r {::reqd1 "abc" ::reqd2 "xyz" ::extra 123}) ; => false
不过,处理此 IMO 的最佳方法是简单地忽略存在您不关心的密钥。
希望随着规范的成熟,这些好东西会被添加进来。或者,也许它们已经存在(变化很快)而我根本不知道。这是 clojure 中一个非常新的概念,所以我们大多数人都需要学习很多东西。
更新 - 2016 年 12 月 我只是想在写完这 6 个月后重温一下。看起来我最初关于忽略您不关心的键的评论是首选方法。事实上,在我两周前参加的 clojure/conj 会议上,Rich 的主题演讲专门讨论了软件所有级别(从功能级别到应用程序级别)的版本控制概念。他甚至在演讲中特别提到了禁止按键的概念,可以在 on youtube 中找到。他说它是有意设计的,因此只能指定必需的键。不允许密钥确实没有任何好处,应该谨慎行事。
关于 :opt
键,我认为原始答案仍然站得住脚——它是文档,实际上,它允许生成这些可选指定的键:
(s/def ::name #{"Bob" "Josh" "Mary" "Susan"})
(s/def ::height-inches (s/int-in 48 90))
(s/def ::person (s/keys :req-un [::name] :opt-un [::height-inches]))
(map first (s/exercise ::person))
; some generated data have :height-inches, some do not
({:name "Susan"}
{:name "Mary", :height-inches 48}
{:name "Bob", :height-inches 49}
{:name "Josh"}
关于可选键的要点是 值 如果它们出现在映射
中则将被验证