3

モジュール: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)

テストのタイプがハッシュマップに変更された場合、それは常に正常です。

私が逃したものは?

4

1 に答える 1

4

test-define.rkt にこの行があることに気付きました

(set! test3 (add1 test))

すべきですtest3test

これは、2 つのゼロが表示された理由を説明している可能性があります (テストは変更されませんでした)。

編集2

便宜上、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 対 0 0 の出力が表示されます。

うーん。なんで?

良い。provide フォームをコントラクトをまったく使用しないように変更すると、出力は 0 1 になります。

コントラクトを追加しても、この動作は変わらないはずです (私はそう思います)。多分バグ?

http://pre.racket-lang.org/docs/html/guide/contracts-gotchas.html?q=contract&q=ignore

言います:

コントラクト ライブラリは、contract-out を介してエクスポートされた変数が割り当てられていないと想定しますが、それを強制しません。そこで、設定してみるなら!これらの変数に驚くかもしれません。...中略... 教訓: これはバグであり、将来のリリースで対処する予定です。

于 2012-07-22T09:15:26.160 に答える