在LISP中,您是否可以构造一个“ check-type”,如果该值不是所有整数键和值的标签,则会引发错误?

发布于 2025-02-03 15:08:14 字数 427 浏览 5 评论 0 原文

假设我有一个功能:

(defun distribution-to-list (distribution)
  (check-type distribution hash-table)
  (loop for key being each hash-key of distribution
    using (hash-value value) nconc (loop repeat value collect key)))

我想确保至少传递的哈希桌子的所有值都是整数,因为我使用它们将其重复为大列表。在内部循环之前,有什么方法可以使用 check-type ?还是在尝试重复字符串时,让内部循环宏宏大误差会是足够好的练习? (或任何非整数类型)

Say I have a function:

(defun distribution-to-list (distribution)
  (check-type distribution hash-table)
  (loop for key being each hash-key of distribution
    using (hash-value value) nconc (loop repeat value collect key)))

I want to ensure that at least all the values of the hash-table that are passed in are integers, as I'm using them to repeat values into a big list. Is there any way to do so with check-type before the inner loop? Or would it be good enough practice to let the inner loop macro throw a type error when it tries to repeat a string? (or whatever non integer type)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清晨说晚安 2025-02-10 15:08:15

如果您可以编写一个可以检查值是否可以接受的函数,则可以使用满足构建类型规范符,例如(满足可接受的)。例如,

(defun all-integer-keys-p (ht)
  (loop for k being each hash-key in ht
        always (integerp k)))

(let ((h (make-hash-table)))
  ;; when the table contains only integer
  ;; keys, we're fine
  (setf (gethash 1 h) 'foo
        (gethash 2 h) 'bar)
  (check-type h (satisfies all-integer-keys-p))

  ;; but a non-integer key will lead to an
  ;; error from CHECK-TYPE
  (setf (gethash 'three h) 'baz)
  (check-type h (satisfies all-integer-keys-p)))

带有的速记(满足All-Integer-keys-p),您可能会发现更多可读性:

(deftype all-integer-key-hash-table ()
  `(satisfies all-integer-keys-p))

(let ((h (make-hash-table)))
  (setf (gethash 1 h) 'foo
        (gethash 2 h) 'bar)
  (check-type h all-integer-key-hash-table)

  (setf (gethash 'three h) 'baz)
  (check-type h all-integer-key-hash-table))

If you can write a function that can check whether a value is acceptable, then you can use satisfies to construct a type specifier, such as (satisfies is-acceptable). E.g.,

(defun all-integer-keys-p (ht)
  (loop for k being each hash-key in ht
        always (integerp k)))

(let ((h (make-hash-table)))
  ;; when the table contains only integer
  ;; keys, we're fine
  (setf (gethash 1 h) 'foo
        (gethash 2 h) 'bar)
  (check-type h (satisfies all-integer-keys-p))

  ;; but a non-integer key will lead to an
  ;; error from CHECK-TYPE
  (setf (gethash 'three h) 'baz)
  (check-type h (satisfies all-integer-keys-p)))

With deftype, you can define a type as shorthand for (satisfies all-integer-keys-p), which you may find more readable:

(deftype all-integer-key-hash-table ()
  `(satisfies all-integer-keys-p))

(let ((h (make-hash-table)))
  (setf (gethash 1 h) 'foo
        (gethash 2 h) 'bar)
  (check-type h all-integer-key-hash-table)

  (setf (gethash 'three h) 'baz)
  (check-type h all-integer-key-hash-table))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文