模块:test-define.rkt
#lang racket
(provide test)
(provide (contract-out [add-test! (-> void)]))
(define test 0)
(define (add-test!)
(set! test (add1 test)))
主程序:act.rkt
#lang racket
(require "test-define.rkt")
(printf "~a~%" test)
(add-test!)
(printf "~a~%" test)
运行act.rkt,我得到:
0
1
这就是我想要的。
但如果我在test-define.rkt中修改合同:
(provide test)
更改为
(provide (contract-out [test integer?]))
然后我再次运行act.rkt,我得到了:
0
0
为什么呢?我无法改变测试值。
如果我提供了一个get func,它会再次恢复正常。
(provide (contract-out [get-test (-> integer?)]))
(define (get-test)
test)
如果测试类型更改为哈希映射,则始终正常。
我错过了什么?
答案 0 :(得分:4)
我注意到在test-define.rkt中你有这一行
(set! test3 (add1 test))
test3
应test
吗?
这可以解释为什么你看到两个零(测试从未改变)。
编辑2
为方便起见,我将两个模块放在同一个文件中 并改变了测试合同:
#lang racket
(module test-define racket
(provide test)
; (provide (contract-out [test integer?]))
(provide get-test)
(provide (contract-out [add-test! (-> void)]))
(define test 0)
(define (add-test!)
(set! test (add1 test)))
(define (get-test)
test))
(module ack racket
(require (submod ".." test-define))
(printf "~a~%" test)
(add-test!)
(printf "~a~%" test))
(require (submod "." ack))
现在我看到了0 1 vs 0 0输出。
嗯。为什么呢?
好。如果我们更改提供表单以不使用合同 根本就是输出为0 1。
添加合同不应该改变这种行为(我认为)。 也许是一个错误?
http://pre.racket-lang.org/docs/html/guide/contracts-gotchas.html?q=contract&q=ignore
表示:
合同库假定通过外包出口的变量 未分配,但不强制执行。因此,如果你尝试 设置!那些变数,你可能会感到惊讶。 ......剪断......道德:这个 是一个我们将在未来版本中解决的错误。