You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Guile Scheme REPL中让GOOPS对象实现友好打印

让Guile GOOPS的对象在REPL中美观打印

这个问题我太熟悉了——Guile的GOOPS对象默认只会输出#<...>这种模糊的占位符,根本看不到实际数据。不过我们可以通过自定义对象的打印逻辑来解决,有两种常用的方法:

方法1:定义类时使用#:print关键字参数

这是GOOPS专门提供的便捷方式,直接在define-class里指定打印函数:

(use-modules (oop goops))

(define-class <vec3> ()
  (e0 #:init-value 0.0 #:init-keyword #:e0)
  (e1 #:init-value 0.0 #:init-keyword #:e1)
  (e2 #:init-value 0.0 #:init-keyword #:e2)
  #:print (lambda (obj port)
            (format port "#<vec3 ~a ~a ~a>"
                    (slot-ref obj 'e0)
                    (slot-ref obj 'e1)
                    (slot-ref obj 'e2))))

(define (make-point x y z)
  (make <vec3> #:e0 x #:e1 y #:e2 z))

测试一下:

scheme@(guile-user)> (define p0 (make-point 1 2 3))
scheme@(guile-user)> p0
$1 = #<vec3 1 2 3>

这样就能直接看到对象的三个分量了,清晰很多。你还可以调整format的字符串,比如改成"(point ~a ~a ~a)",打印出来就是(point 1 2 3),更贴近Scheme的语法风格。

方法2:为类定义write方法

Guile的REPL在打印值时会调用标准的write过程,我们可以为<vec3>类自定义这个方法:

(use-modules (oop goops))

(define-class <vec3> ()
  (e0 #:init-value 0.0 #:init-keyword #:e0)
  (e1 #:init-value 0.0 #:init-keyword #:e1)
  (e2 #:init-value 0.0 #:init-keyword #:e2))

(define-method (write (obj <vec3>) port)
  (format port "#<vec3 ~a ~a ~a>"
          (slot-ref obj 'e0)
          (slot-ref obj 'e1)
          (slot-ref obj 'e2)))

(define (make-point x y z)
  (make <vec3> #:e0 x #:e1 y #:e2 z))

这个方法和第一种效果完全一致,只是实现方式不同——#:print本质上也是帮你注册了对应的打印方法,而直接定义write方法更符合Scheme的标准过程扩展逻辑。

内容的提问来源于stack exchange,提问作者tkf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:30:08