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

Har*_*ier 5 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) 
Run Code Online (Sandbox Code Playgroud)

要使它工作,我需要用以下代码替换最后两行:

(point-in-plane-pos_x a-pixel) 
(point-in-plane-pos_y a-pixel) 
Run Code Online (Sandbox Code Playgroud)

同样在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))
Run Code Online (Sandbox Code Playgroud)

给出了类似的错误.

是什么原因Scheme(和Racket)不允许您通过以下方式访问父类中定义的子类型的字段:subtypeID-fieldID而不是parenttypeID-fieldID

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

Asu*_*awa 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
Run Code Online (Sandbox Code Playgroud)

这是因为结构体并不真正了解字段名称.从Racket文档:"结构类型的字段基本上是未命名的,但支持出于错误报告目的而支持名称." 您必须禁止此行为才能获得子结构的额外访问器.


dyo*_*yoo 6

文件的的结构形式表示,它提供了一个给定的领域存取和setter方法,但是并不表示它会自动与你期待额外的名字重新暴露父类型的现有存取和setter.

当我处理结构并按名称拉出组件时,我经常使用racket/match库,尤其是struct* pattern matcher.通常,我必须处理结构的多个组件,并且匹配器可以很容易地执行此操作.