我正在追随球拍的境界。下面的代码抛出以下错误:
coord-lat: contract violation
expected: coord?
given: #<void>
#lang racket
(require 2htdp/universe 2htdp/image)
(struct coord (alt lat) #:transparent #:mutable)
(define WIDTH 400)
(define HEIGHT 400)
(define UFO *some_picture*)
(define (move-ufo pos)
(place-image/align UFO
(coord-alt pos)
(coord-lat pos)
"left" "top"
(empty-scene WIDTH HEIGHT)))
(define (increment pos)
(set-coord-alt! pos (+ 2 (coord-alt pos)))
(set-coord-lat! pos (+ 1 (coord-lat pos))))
(define (at-the-border pos)
(>= (coord-lat pos) (- HEIGHT 20)))
(big-bang (coord 0 0)
(on-tick increment)
(to-draw move-ufo)
(stop-when at-the-border))
为调试添加(coord? pos)
条件,确认坐标不是坐标。在下面的大爆炸函数之前将当前状态定义为坐标也不能解决错误:
(define s (coord 0 0))
(big-bang s...
我检查了球拍contract和struct文件,但找不到原因。由于使用了define-struct
的许多示例,我也尝试了make-coord
,但这也无济于事。球拍文件还建议struct is preferred。
向协调员添加合约
(provide coord)
(define-struct/contract coord ([alt number?]
[lat number?])
#:transparent
#:mutable)
导致以下错误:
coord-lat: contract violation
expected: coord?
given: #<void>
in: the 1st argument of
(-> coord? number?)
contract from: (struct coord)
blaming: fly-ufo.rkt
at: fly-ufo.rkt
这里可能是错误的原因是什么?
@Greg Hendershott:set-coord-alt!是in the struct document of racket为:
set-id-field-id!,用于包含#:mutable选项的每个字段,或者当#:mutable选项指定为struct-option时;一个mutator过程,它接受结构类型的实例和新的字段值。使用新值破坏性地更新结构,并返回#<void>
。
所以,当我读完最后一句话时,我得到了函数返回#<void>
的原因,我之前错过了它。因此,为了返回坐标而不是#<void>
,我在增量函数的末尾添加了pos
:
(define (increment pos)
(set-coord-alt! pos (+ 2 (coord-alt pos)))
(set-coord-lat! pos (+ 1 (coord-lat pos)))
pos)
并且有效。
我把这个只是为了将来的参考。在Metaxal注意到应该创建一个新结构之后,我更新了结构如下:
;; a struct for the current state, where:
;; field 1 is x coordinate
;; field 2 is y coordinate
;; field 3 is horizontal speed
;; field 4 is vertical speed
(struct cs (lat alt hspeed vspeed))
此后,停止不明飞行物变得如此简单:
(define (stop ufo)
(cs (cs-lat ufo) (cs-alt ufo) 0 0))
并且加速成为:
(define (up-wards ufo)
(cond [(> (cs-vspeed ufo) (- MAX-SPEED))
(struct-copy cs ufo [vspeed (sub1 (cs-vspeed ufo))])]
[#t (play-sound some-sound-file #t)
ufo]))
现在我唯一想知道的是,将play-sound-file
和ufo
置于else分支的级联中是否是必要的风格。
答案 0 :(得分:0)
一般来说,当一个函数应该返回一个值时,你会得到像given: #<void>
这样的错误,但是没有。例如,坏:
(define (increment x)
(set! x (add1 x)))
;; set! returns void, therefore increment returns void
VS。好:
(define (increment x)
(add1 x))
;; returns a number
虽然我不熟悉大爆炸,但看起来你有类似的问题:
(define (increment pos)
(set-coord-alt! pos (+ 2 (coord-alt pos)))
(set-coord-lat! pos (+ 1 (coord-lat pos))))
. . . .
(big-bang (coord 0 0)
(on-tick increment)
(to-draw move-ufo)
(stop-when at-the-border))
看起来on-tick
中big-bang
子句的所有变体都应该返回HandlerResult
,而不是#<void>
。
什么是set-coord-alt!
以及它返回了什么?