如何强制执行此结构中的字段类型?
#lang racket
(struct Car (model year))
Run Code Online (Sandbox Code Playgroud)
我尝试过使用合同(但是因为我是新手,所以这个显然不起作用......:P)
(provide (contract-out
[Car (string? integer? . -> . Car?)]))
Run Code Online (Sandbox Code Playgroud)
示例:这已成功但不应该......
(define my-car (Car 2008 "A3"))
可悲的是,它似乎没有写在任何地方如何完成这项工作.
我认为你至少打了一个,也许是以下两个:
使用(provide (contract-out ....))意味着合同仅适用于模块边界 - 仅适用于此模块的其他模块require.因此,如果您的测试示例位于同一模块中,则该合同将不适用.相反,您可以使用define/contract合同来应用于事物本身,无论是在定义它的模块中还是在外部(如果provide它).
s有一种特殊形式的合同struct,您可以在其中为每个字段指定合同.你在上面尝试的只是构造函数的契约.虽然这可能是你想要的,但考虑使用合同struct代替.
将两者结合起来你可以做到:
;; Define the contract on the struct itself.
;; Contract is used even within this module.
(provide car)
(define-struct/contract car ([model string?]
[year integer?]))
Run Code Online (Sandbox Code Playgroud)
如果您确实希望合同仅适用于模块边界,那么您将使用:
;; Define the contract only as `provide`d.
;; Contract is used only for code `require`-ing this module.
(provide (contract-out (struct car ([model string?]
[year integer?]))))
(struct car (model year))
Run Code Online (Sandbox Code Playgroud)
ps在Racket中的FWIW常见的风格不是大写结构名称 - car不是Car.
更新:只是为了更清楚地说明差异:
#lang racket
(module mod racket
(provide car0)
(define-struct/contract car0 ([model string?]
[year integer?]))
(car0 "foo" "bar") ;; gives contract violation
;; because contract on struct itself
(struct car1 (model year))
(provide (contract-out (struct car1 ([model string?]
[year integer?]))))
(car1 "foo" "bar") ;; does NOT give contract violation
;; because contract only on the `provide`
)
(require 'mod)
(car0 "foo" "bar") ;; gives contract violation
(car1 "foo" "bar") ;; gives contract violation
Run Code Online (Sandbox Code Playgroud)