Scheme和Racket中访问结构子类型字段

5
在Racket中,这会给我一个错误:
(struct point-in-plane  (pos_x pos_y))  
(struct pixel point-in-plane (color))  

(define a-pixel (pixel 1 2 "blue"))  
(pixel-color a-pixel)  
(pixel-pos_x a-pixel) 
(pixel-pos_y a-pixel) 

为了让它工作,我需要将最后两行替换为:
(point-in-plane-pos_x a-pixel) 
(point-in-plane-pos_y a-pixel) 

同样的,在R6RS中

#!r6rs
(import (rnrs))
(define-record-type point (fields x y))
(define-record-type cpoint (parent point) (fields color))
(define blue-point  (make-cpoint 1 2 "blue"))
(write (cpoint-x blue-point))

出现了类似的错误。

Scheme(和Racket)为什么不允许您访问在父级中定义的子类型的字段,而不是通过parenttypeID-fieldID而是subtypeID-fieldID呢?

也就是说,在我的情况下,允许我使用pixel-pos_x和pixel-pos_y。

2个回答

8

一个原因是struct允许您定义具有相同名称字段的子结构。例如:

(struct base (x y))
(struct sub base (x y))

(define rec (sub 1 2 3 4))
(base-x rec) ; => 1
(sub-x rec)  ; => 3

这是因为结构体不真正了解字段名称。根据Racket文档的说明:"结构体类型的字段基本上没有名称,尽管支持错误报告目的的名称。" 为了获取子结构的额外访问器,您必须禁止此行为。

6

结构体形式的文档说明提供了给定字段的访问器和设置器,但没有说明它会自动重新公开父类型的现有访问器和设置器,以及您期望的额外名称。

当我处理结构体并按名称提取组件时,我经常使用racket/match库,特别是struct*模式匹配器。通常,我必须处理结构体的多个组件,而匹配器使这样做变得容易。


谢谢你,Daniel。如果你手头有例子可以发给我(发送至harryspier@hotmail.com),那将对我非常有帮助。 - Harry Spier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接