我有一个返回类定义的方法:
(define (max-tracker%)
(let ([current-maximum 0])
(class object%
(init val) ; <--
...
(define held-value 0)
(set-val val)
(define/public (set-val newval) ; <--
(when (newval . >= . current-maximum)
(set! current-maximum newval))
(set! held-value newval))
...
)))
如何将合约绑定到set-val
方法?
答案 0 :(得分:4)
您可以使用with-contract
表单,该表单允许您在表达式中创建任意合约区域:
(define (max-tracker%)
(with-contract
max-tracker-procedure
#:result contract-expr
(class object% (init val) ...)))
这将创建一个名为max-tracker-procedure
的合同区域,该区域只导出一个必须符合contract-expr
中指定的合同的匿名值。在这种情况下,您可以指定class/c
合同。通过使用Racket返回多个值并使用#:results (contract-expr ...)
的能力,也可以指定多个值和导出。这是一个更简单的例子来证明这一点:
(define test-value
(with-contract test
#:result (or/c integer? symbol?)
"neither int nor symbol - should break contract"))
运行它应该会给你:
broke its contract:
promised: (or/c integer? symbol?)
produced: "neither int nor symbol - should break contract"
in: (or/c integer? symbol?)
contract from: (region test)
blaming: (region test)
将此与class/c
相结合可以为您提供所需的信息。
这是一个更接近你想要的例子:
(define (with-greeting class%)
(with-contract with-greeting
#:result (class/c [greet (->m string? string?)])
(class class%
(super-new)
(define/public (greet person)
(string-append "Hello, " person "!")))))
(define simple-greeter% (with-greeting object%))
(define simple-greeter (new simple-greeter%))
(send simple-greeter greet "Jack")
(send simple-greeter greet 'Jack)