【问题标题】:Unexpected behavior in Common Lisp type specifiersCommon Lisp 类型说明符中的意外行为
【发布时间】:2021-12-27 19:49:07
【问题描述】:

我刚刚阅读了 CL 中的类型,我发现了以下行为,例如关于vector类型的附属类型信息有点令人费解:

(let ((v1 (vector 1 3))
      (v2 (vector 1 3 4))
      (v3 (vector 1 3 "4")))
  (values
   (typep v1 '(vector (satisfies oddp)))
   (typep v2 '(vector (satisfies oddp)))
   (typep v3 '(vector (satisfies oddp)))))

根据spec,向量复合类型的第一个参数表示元素类型,因此上面的类型说明符应该匹配一个向量与满足oddp的元素,对吧?那么为什么所有类型检查都t呢?!?! @_@

这个问题的解决办法是

(defun vector-of-oddints-p (v)
  (and
   (vectorp v)
   (every #'(lambda (n) (and (integerp n) (oddp n))) v)))

(let ((v1 (vector 1 3))
      (v2 (vector 1 3 4))
      (v3 (vector 1 3 "4")))
  (values
   (typep v1 '(satisfies vector-of-oddints-p))
   (typep v2 '(satisfies vector-of-oddints-p))
   (typep v3 '(satisfies vector-of-oddints-p))))

但这感觉很笨拙,上面的类型说明符应该可以工作。

【问题讨论】:

  • 在向量上调用TYPE-OF,看看它返回什么。
  • @Rainer Joswig 它按预期返回简单向量(向量的子类型)。不知道这意味着什么。

标签: types common-lisp


【解决方案1】:

谢谢@Halbert 和@Rainer Joswig;我今天学到了一些关于数组的东西!

因此,类型说明符'(vector (satisfies oddp)) 实际上表示一个向量,可以(但不一定非必须)包含满足oddp 谓词的元素。 (参见 Rainer 的回答:https://stackoverflow.com/a/21066478/6455731

不出所料,spec 实际上在这方面很有教育意义:

如果 element-type 是符号 *,则不排除数组 他们的元素类型。否则,仅包含那些数组 实际数组元素类型是升级元素类型的结果。

array upgrading 上的部分也提供了丰富的信息,例如关于上面提到的“实际数组元素类型”:

在创建数组期间,请求的元素类型是 称为表示数组元素类型。升级后的数组元素 表示的数组元素类型的类型变为实际数组 创建的数组的元素类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    相关资源
    最近更新 更多