球拍模块合同让我很困惑

时间:2012-07-22 07:35:55

标签: racket

模块: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)

如果测试类型更改为哈希映射,则始终正常。

我错过了什么?

1 个答案:

答案 0 :(得分:4)

我注意到在test-define.rkt中你有这一行

(set! test3 (add1 test))

test3test吗?

这可以解释为什么你看到两个零(测试从未改变)。

编辑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

表示:

  

合同库假定通过外包出口的变量   未分配,但不强制执行。因此,如果你尝试   设置!那些变数,你可能会感到惊讶。 ......剪断......道德:这个   是一个我们将在未来版本中解决的错误。

相关问题