简体   繁体   English

可选的struct字段

[英]Optional struct field

I have searched the documentation for Racket (the language; non-typed) and have been unable to decide if it is possible to have optional arguments for a non-mutable struct. 我搜索了Racket(语言;非类型)的文档 ,并且无法确定是否可以为非可变结构提供可选参数。 I would like to be able to do: 我希望能够做到:

(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) ...

In this pseudo-example, #syntax? 在这个伪示例中, #syntax? is just a placeholder for where I suspect some special syntax might reside to make the following field optional. 只是一个占位符,我怀疑可能存在一些特殊语法,以使以下字段可选。 Is there a way to make your everyday, immutable, run-of-the-mill struct have optional arguments in base Racket? 有没有办法让你的日常,不可变,一般的结构在基础Racket中有可选参数?

Clarification: If a struct is created without the optional parameter, it is filled in with a default value that must be supplied at creation time. 澄清:如果在没有可选参数的情况下创建结构,则使用必须在创建时提供的默认值填充该结构。 In this instance, that information would have to be contained inside of the (perhaps poorly named) #syntax? 在这种情况下,该信息必须包含在(可能名称#syntax?#syntax? block. 块。

(Note: I have reservations regarding the inclusion of the struct tag to this question as it mentions the C family of languages to which Racket does not belong...) (注意:我对这个问题中包含struct标签有所保留,因为它提到了Racket不属于的C语言系列......)

I think the easiest way to do what you want is to create a "constructor" that has an optional argument, like this: 我认为最简单的方法就是创建一个具有可选参数的“构造函数”,如下所示:

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

Racket also has a full-blown class system, with ... pretty much everything you can imagine. Racket还有一个完整的类系统,几乎可以想象的一切。 For this use, though, I think I'd just do it like this. 但是,对于这个用途,我想我就是这样做的。

If the default value of the optional field is meaningful, then I'd do what John suggested in his comment -- simply define a custom constructor: 如果可选字段的默认值有意义,那么我会按照他在评论中建议的那样做 - 只需定义一个自定义构造函数:

(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")

However if the default value of opt really means N/A, then I might instead define two struct s: The general case, and the specialized one derived from the special one: 但是,如果opt的默认值实际上意味着N / A,那么我可能会改为定义两个struct :一般情况,以及从特殊情况派生的专用结构:

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

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

Code that only knows/cares about general can treat instances of general and special as such: 只知道/关心general可以处理generalspecial实例:

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

Code that cares specifically about special can check for that: 专门关注special代码可以检查:

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

I would probably only do this for a real "is-a" ("is a kind of") relationship -- if it sounds natural to say that " special is a kind of general ". 我可能只会做一个真正的“is-a”(“是一种”)关系 - 如果说“ special 是一种 general ”听起来很自然。


Of course if you're really getting into this kind of OOP territory, you could use racket/class . 当然,如果你真的进入这种OOP领域,你可以使用racket/class

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM