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

时间:2011-12-23 20:03:26

标签: scheme racket

在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)不允许您访问父级中定义的子类型的字段的原因是: subtypeID-fieldID而不是parenttypeID-fieldID

即。在我的情况下允许我使用pixel-pos_x和pixel-pos_y。

2 个答案:

答案 0 :(得分: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 documentation:“结构类型的字段基本上是未命名的,但支持错误报告的名称。”您必须禁止此行为才能获得子结构的额外访问器。

答案 1 :(得分:6)

struct 表单的documentation表示它为给定字段提供了访问器和setter,但并没有说它会自动重新公开现有的访问器和setter具有您期望的额外名称的父类型。

当我处理结构并按名称提取组件时,我经常使用racket/match库,特别是使用struct*模式匹配器。通常,我必须处理结构的多个组件,并且匹配器可以很容易地执行此操作。