2014-02-20 2 views
4

Я искал documentation для Racket (язык, не типизированный) и не смог решить, возможно ли иметь необязательные аргументы для не изменяемой структуры. Я хотел бы быть в состоянии сделать:Необязательное поле структуры

(struct q-a-website (name interest-value #syntax? some-optional-field)) 
... (q-a-website "stack-overflow" 42 "My name is Jon Skeet") ... 
... (q-a-website "quora" -inf.0) ... 

В этом псевдо-примере #syntax? просто заполнитель, где я подозреваю, что некоторые специальный синтаксис может находиться, чтобы сделать следующее поле необязательно. Есть ли способ сделать вашу повседневную, неизменную, run-of-the-mill структуру необязательными аргументами в базовом Racket?

Уточнение: если структура создается без необязательного параметра, она заполняется значением по умолчанию, которое должно быть предоставлено во время создания. В этом случае эта информация должна содержаться внутри блока (возможно, плохо названного) #syntax?.

(Примечание: У меня есть оговорки относительно включения struct тега на этот вопрос, как он упоминает C семейство языков, к которым Ракетка не принадлежит ...)

+0

Можете ли вы немного разъяснить свою желательную семантику? Например: что должно произойти, когда вы запрашиваете необязательное поле для структуры, которая его не имеет? Я думаю, что я направляюсь к простому предложению пользовательского «конструктора», но мы увидим ... –

+0

То же самое, что и Джон. Также рассмотрим наследование. –

+0

@JohnClements Я не уверен, что вы просите, но я ищу значения по умолчанию, которые будут созданы, если поле не указано. Я отредактирую свой вопрос. – BlackVegetable

ответ

5

Я думаю, что самый простой способ сделать то, что вы хотите, чтобы создать «конструктор», который имеет необязательный аргумент, как это:

#lang racket 

(struct q-a-website (name interest-value optional-field)) 

;; make a q-a-website 
(define (make-q-a-website name interest-value [optional-field #f]) 
    (q-a-website name interest-value optional-field)) 

;; try making it with and without the optional argument: 
(make-q-a-website "stack-overflow" 42 "My name is Jon Skeet") 
(make-q-a-website "quora" -inf.0) 

Ракетка также имеет полнофункциональную систему класса, с ... в общем, все, что вы можете себе представить. Для этого использования, я думаю, я просто сделаю это так.

+0

ОК, это странное время.Я написал свой ответ, затем сделал одно редактирование ... затем заметил, что вы отправили ответ. Который я поддержал. :) –

+0

Это было направление, которое я подозревал, было правильно. Однако я не знал опции '[optional-field #f]'. Спасибо. – BlackVegetable

+1

Если у вас много полей в вашей 'struct', и вы хотите, чтобы большинство из них были необязательными, вы, вероятно, захотите использовать [аргументы ключевого слова] (http://docs.racket-lang.org/guide/lambda.html #% 28part._lambda-keywords% 29) вместо необязательных аргументов для конструктора. – Metaxal

3

Если значение по умолчанию необязательного поля имеет смысл, то я бы делать то, что Джон предложил в своем комментарии - просто определить пользовательский конструктор:

(struct s (a b opt)) 

(define (make-s a b [opt #f]) 
    (s a b opt)) 

(make-s "a" "b") 
(make-s "a" "b" "opt") 

Однако, если значение по умолчанию opt действительно означает N/A, то я мог бы вместо того, чтобы определить два struct S: общий случай, и специализированный один производный от специального одного:

(struct general (a b)) 
(struct special general (opt)) 

(define g (general "a" "b")) 
(define s (special "a" "b" "opt")) 

код, который только знает/заботится о general могут относиться случаи general и special как таковой:

(general? g) ; #t 
(general? s) ; #t 

код, который заботится конкретно о special может проверить, что:

(special? g) ; #f 
(special? s) ; #t 

я бы, вероятно, только сделать это для реального " («является своего рода») - если звучит естественно сказать, что «special- это своего родаgeneral».


Конечно, если вы действительно получаете в такого рода территории ООП, вы могли бы использовать racket/class.

Смежные вопросы