2013-06-09 6 views
6

Come si impone il tipo di campi in questa struttura?Come impongo che il campo di una struttura sia di qualche tipo?

#lang racket 
(struct Car (model year)) 

Ho provato con un contratto (ma visto che sono nuovo al racket, questo non funziona, ovviamente ...: P)

(provide (contract-out 
     [Car (string? integer? . -> . Car?)])) 

esempio: Questo succeds ma non dovrebbe ...

(define my-car (Car 2008 "A3"))

Purtroppo, non sembra essere scritto da nessuna parte come per ottenere questo fatto.

risposta

6

penso che si sta colpendo almeno uno, e forse entrambe le seguenti:

  1. Utilizzando (provide (contract-out ....)) significa il contratto si applica solo al confine del modulo - solo per altri moduli che require questo uno. Quindi, se il tuo esempio di test era nello stesso modulo, il contratto non si applicava. Invece è possibile utilizzare define/contract per applicare un contratto alla cosa stessa, sia nel modulo in cui è definito sia all'esterno se si è provide esso.

  2. C'è un special form of contracts for structs, in cui si specifica un contratto per ogni campo. Quello che hai provato sopra è un contratto solo sulla funzione del costruttore. Anche se lo potrebbe essere essere quello che vuoi, prendere in considerazione l'utilizzo del contratto per il struct invece.

Combinando entrambi si potrebbe fare:

;; Define the contract on the struct itself. 
;; Contract is used even within this module. 
(provide car) 
(define-struct/contract car ([model string?] 
          [year integer?])) 

Se si voleva il contratto di applicare solo al confine del modulo, allora si può usare:

;; 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)) 

P.S. FWIW in Racket lo stile comune è non per scrivere in maiuscolo il nome di una struttura - car non Car.


Aggiornamento: Giusto per illustrare la differenza più chiaramente:

#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 
+0

BTW una cosa bella di contratti è che non si limitano a "tipi" in C/C++ senso. Per esempio se l'automobile fosse stata inventata nel 1769, allora il tuo contratto per 'year' potrebbe essere' (e/c intero? (>/C 1768)) 'invece di solo' intero? '. ;) –

+0

Grazie mille, ha funzionato perfettamente :) – TesX

Problemi correlati