gpt4 book ai didi

error-handling - 是否可以根据有限范围变量的超出范围值覆盖 Common Lisp 中的类型错误行为?

转载 作者:行者123 更新时间:2023-12-03 07:50:27 25 4
gpt4 key购买 nike

抱歉,如果问题的主题措辞奇怪(因为缺乏更好的术语——这也是我在谷歌上搜索这个特定主题时没有找到任何东西的原因之一),所以这就是我的意思。

假设这个函数 foobar 被定义:

(defun foobar (x)
(declare (type (integer -100 100) x))
(format T "X is ~A~%" x))

所以对于声明行,x 是一个整数,必须是 -100、100 或介于两者之间的任何整数。因此,这样做会产生错误:
CL-USER> (foobar 101)

The value 101 is not of type (INTEGER -100 100).
[Condition of type TYPE-ERROR]

Restarts:
(blah blah blah)

除了将函数本身更改为显式地进行钳位之外,是否有一种方法可以指定覆盖行为,以便在不改变 foobar 本身的 defun 的情况下执行此操作:
(foobar [any-value-over-100])

将其限制为 100,同样使用 x < -100,而函数体本身没有额外的代码行来执行此操作?

编辑:回答一个响应者,这是钳制 - 将值严格保持在定义的最小和最大范围内。在 Lisp 中,这是一个示例:
CL-USER> (defun clamp (x min max)
(if (> x max)
max
(if (< x min)
min
x)))
CLAMP
CL-USER> (clamp 5 4 9)
5
CL-USER> (clamp -2 4 9)
4
CL-USER> (clamp 123 4 9)
9

虽然我可以很容易地把它变成一个宏并将它放在任何函数的开头(我有一种奇怪的感觉,这最终将是我必须做的),这个问题是问是否有可能告诉 Common Lisp 错误处理程序“只使用值来执行此操作!”,而不是让它像通常那样中断整个程序流。

最佳答案

Common Lisp 中的类型声明

你的代码:

(defun foobar (x)
(declare (type (integer -100 100) x))
(format T "X is ~A~%" x))

上面调用的结果类似于 (foobar 120)在 Common Lisp 中完全未定义。
  • 它可能会被完全忽略
  • 它可能会导致错误或各种运行时问题
  • 它可以帮助编译器创建更好的代码(这是顺便说一句。这些声明的主要原因)
  • 它可以在编译/或运行时进行类型检查。只有极少数的 Lisp 编译器会这样做。

  • Common Lisp 中的可移植运行时类型检查

    如果您想以便携方式检查运行时类型错误,请使用 CHECK-TYPEASSERT .
    (defun foobar (x)
    (check-type x (integer -100 100))
    (format T "X is ~A~%" x))

    建议

    在 Lisp 中扩展函数而不更改其源代码称为“建议”。这不在 Common Lisp 标准中的普通功能,但应该有工具,编写这样的东西并不难。

    扩展通用函数

    Common Lisp 为泛型函数内置了这种机制。标准方法组合有 :before、:after 和 :around 建议。
    (defmethod foobar ((x integer))
    (check-type x (integer -100 100))
    (format T "X is ~A~%" x))

    在 Common Lisp 中,不能在任意类型上分派(dispatch) - 只能在类上分派(dispatch)。有一些基本类型的类,如字符串、整数、...这里我们使用 xinteger .

    如果要夹 foobarx :
    (defmethod foobar :around ((x integer))
    (call-next-method (clamp x -200 100)))

    以上是 :around方法。我调用了下一个方法,即上面的方法,但参数已更改。只要参数类不改变调度,这是允许的。

    替代方法:宏

    一个目标可能是编写更少的代码并让代码更具声明性。

    也许有人想写:
    (defun-clamped foobar ((x (integer :min -100 :clampled-max 100)))
    (format T "X is ~A~%" x))

    那我就写 defun-clamped宏,扩展为普通 DEFUN ,它做了必要的事情。

    关于error-handling - 是否可以根据有限范围变量的超出范围值覆盖 Common Lisp 中的类型错误行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20206784/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com