Clojure处理对不存在的字段的请求

时间:2016-06-15 12:07:27

标签: clojure

当所请求的元素不存在时,Clojure会发生什么变化:

(get {:a 1} :b) ; nil, no b
(second [0]) ; nil, only one element.
; nil seems to be by far the most common but:
(nth [0] 1) ; ERROR: java.lang.IndexOutOfBoundsException.
(nth nil 1) ; but this works (returning nil)

在返回nil和何时抛出错误时是否有一般逻辑?

3 个答案:

答案 0 :(得分:3)

get通过集合中的键进行查找。它适用于地图和矢量(索引是键)。如果找不到密钥,查找将返回nil

second适用于seq,实际上是在nextfirst之上实施的。当没有可用值时,它们返回nil(添加rest,当没有可用值时返回空seq

nth适用于序列,并假设可以在集合中找到所请求的索引。

至于它们背后的逻辑,我认为它给你一个选择,并决定索引是否超出界限是错误还是有效状态。通过在getnth之间进行选择,您可能会决定快速失败或使用nil作为默认值。

答案 1 :(得分:3)

对我来说逻辑是:

  • nth:您认为数据存在并且您想拥有其索引
  • get:它更具探索性,你要求数据,如果它不存在则不返回任何内容

在这两种情况下,如果找不到值,您都可以传递值

(nth [1 2] 3 nil) = nil

修改

从更实际的角度来看,我还会添加这些输入。

一般情况下,您将在Clojure程序中处理几个"行" /"记录"而不是单一数据。想象一下,你有一个像

这样的项目列表
({:name "A" :type "bicycle" :range "premium"} {:name "B" :type "helmet"}) 

这里有一个项目列表(例如在商店中)。我们假设您已经为您的双线圈定义了范围,但没有为头盔定义范围,因此对于与头盔相关的记录,此属性不存在。 然后,如果您使用map(或reduce等)处理所有这些数据,您可能需要为:range输出默认值,例如" normal"或"无"以便在UI上显示它。 您还可以根据结果使用condfilter来分割数据。 等

函数nth用于向量。首先,使用向量集合来表示记录将是一个很难的(子集合OK,但不是主集合)。如果我真的想要使用它而不是hashmap来规范化数据结构,那么它将是一个恒定的长度并且位置明确定义(例如[purchase_price selling_price]。 因此,如果我将nth用于大数据,那么它将用于子集合。

首先我"查询"主要收藏

((first items) :name) = "A"

然后在辅助表上,我将跟踪位置(例如,如果我有一个向量来表示按用户分数排序的项目;向量是为排序数据制作的)

(nth ranks "A")

这里我知道该文章存在,如果不在排名表中,则表示数据存在问题,因此我想要一个错误。

矢量 - >同质或分类数据 地图/记录 - >可能存在的非排序属性

答案 2 :(得分:0)

通常nil是首选(尽管这可能是特定于上下文的),因为它更容易使用。在您的情况下,而不是nth,您可以使用get,它也适用于矢量:

=> (get [0] 1)
nil
=> (get nil 1)
nil