【问题标题】:defstruct - :read-only is not read onlydefstruct - :read-only 不是只读的
【发布时间】:2021-05-13 15:13:32
【问题描述】:

在我为:read-only x 阅读的 CLHS 中:“当 x 为真时,这指定此插槽不能更改;它将始终包含在构造时提供的值。”

我可以做到这一点(CCL、SBCL):

CL-USER> (defstruct foo
           (one 0 :read-only t))
FOO
CL-USER> (defparameter *foo* (make-foo))
*FOO*
CL-USER> *foo*
#S(FOO :ONE 0)
CL-USER> (setf (slot-value *foo* 'one) 1)
1 (1 bit, #x1, #o1, #b1)
CL-USER> *foo*
#S(FOO :ONE 1)

Lisp 不应该禁止更改此插槽吗?

【问题讨论】:

    标签: lisp common-lisp


    【解决方案1】:

    slot-value 不是您访问其类由defstruct 定义的对象的字段的方式。这样的对象根本没有可移植的命名槽:它们命名为 accessors

    某些实现会为此类对象的字段提供名称,并且还可能允许使用 slot-value 访问它们:然而,这种行为是完全不可移植的。

    如果您使用标准定义的语言,那么您应该无法修改使用 :read-only 选项定义的结构字段的值。

    【讨论】:

      【解决方案2】:

      规范说:

      setf 将不接受此插槽的阅读器功能

      slot-value 不是defstruct 创建的阅读器函数。阅读器函数是foo-one(除非您使用:conc-name 关键字覆盖命名方案)。所以如果你尝试这样做,你应该会得到一个错误

      (setf (foo-one *foo) 1)
      

      【讨论】:

      • 确实如此。无法使用读卡器设置插槽。虽然描述中的“它将总是包含”有点误导 IMO。
      • @Manfred:这不是误导。在符合标准的程序中,它确实总是包含初始值。在不符合标准的程序中它可能不会:它可能确实包含数百个小守护进程和橙色烟雾
      猜你喜欢
      • 2021-11-09
      • 2011-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-01
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      相关资源
      最近更新 更多