Overloading a struct constructor?

后端 未结 2 1323
死守一世寂寞
死守一世寂寞 2021-01-19 19:36

My question is the same as the one asked here, but the answer given there doesn\'t actually work.

I have a bunch of structs inheriting from a parent struct A

2条回答
  •  孤城傲影
    2021-01-19 19:54

    Looking further into the new struct keywords that soegaard mentioned, I think I've come up with a solution that's a bit cleaner and, more importantly, much easier to abstract into a macro (those modules and requires were giving me a really hard time). I thought I'd share it for future reference. Again, this requires one of the nightly Racket builds. I'm using 6.5.0.7.

    (Note: the use of case-lambda over defining keyword arguments here is just my preference.)

    #lang racket
    
    (require (for-syntax syntax/transformer))
    
    (struct horse (color)
      #:name Horse
      #:constructor-name Horse
      #:transparent)
    
    (define make-horse
      (case-lambda
        [() (Horse "black")]
        [(color) (Horse color)]))
    
    (define-match-expander horse
      ; match expander
      (λ (pat)
        (syntax-case pat ()
          [(_ more ...) #'(Horse more ...)]))
    
      ; constructor
      ; edit: changing this to use make-variable-like-transformer,
      ;  as suggested in the comments.
      #;(syntax-id-rules ()
          [(_ args ...) (make-horse args ...)]
          [horse Horse])
      (make-variable-like-transformer #'make-horse))
    

    Sample usage:

    > (define black-beauty (horse))
    > black-beauty
    (horse "black")
    
    > (define ginger (horse "red"))
    > ginger
    (horse "red")
    
    > (match black-beauty
        [(horse color) color])
    "black"
    
    > (match ginger
        [(horse color) color])
    "red"
    
    > (horse-color black-beauty)
    "black"
    
    > (horse-color ginger)
    "red"
    

    In short: instantiation, matching, and accessing fields seem to work as you would expect if you'd just used struct. The struct id can also be used as an identifier without any syntax issues. I don't really think that part has much practical use, but I thought it was nice.

提交回复
热议问题