Could we know if a StructTag key exists, even if it has an empty value?

781 views
Skip to first unread message

Matthew Holt

unread,
Dec 14, 2013, 11:04:28 AM12/14/13
to golan...@googlegroups.com
I'm thinking of something similar to accessing map keys:

value, ok := someMap[key]

Where `ok` is true or false, depending on if the key exists in the map. This is tremendously helpful.

Similarly, I think it would be really convenient to know if a struct field tag exists, even if its value is "". I'm talking about this function: http://golang.org/pkg/reflect/#StructTag.Get

For instance, to mark a field as required for Martini, you have a field tag like this:
type BlogPost struct {
    Title   string `form:"title" json:"title" required`
Notice "required" is tacked on at the end. This doesn't break the existing implementation of the tag parser, but it would be nice to know if the "required" tag exists, even if its value is empty string "":

tagValue, ok := structField.Get("required");

I realize this is not necessarily backward-compatible, so what about a new function on StructField like .Tag() or .Has() or something?

I'm asking because If this is never going to happen, because otherwise we're going to change the interface to "binding" package in martini-contrib: https://github.com/codegangsta/martini-contrib/issues/60#issuecomment-30576449 to decide upon a permanent tag format that's more verbose and less convenient: 'validate:"required"`.
Message has been deleted

Matthew Holt

unread,
Dec 14, 2013, 11:29:48 AM12/14/13
to golan...@googlegroups.com
Yup, already done. But as one user points out in that issue, it does break Go convention. It is more convenient than `required:"true"` or `validate:"required"` which seems unnecessarily verbose. One of Go's great mantras is brevity, but it's lacking here. I'm willing to submit new code for review, but I'm skeptical about how it would be received.

On Saturday, December 14, 2013 9:25:55 AM UTC-7, Islan Dberry wrote:
A StructTag is a string. You can write your own parser for this string in martini-contrib. 

Kamil Kisiel

unread,
Dec 14, 2013, 12:14:32 PM12/14/13
to golan...@googlegroups.com
> One of Go's great mantras is brevity

Citation needed ;)
Message has been deleted

Matthew Holt

unread,
Dec 14, 2013, 12:22:17 PM12/14/13
to golan...@googlegroups.com
Valid point.


On Saturday, December 14, 2013 10:16:05 AM UTC-7, Islan Dberry wrote:
On Saturday, December 14, 2013 8:29:48 AM UTC-8, Matthew Holt wrote:
Yup, already done. But as one user points out in that issue, it does break Go convention. It is more convenient than `required:"true"` or `validate:"required"` which seems unnecessarily verbose.

In the Go convention, the key provides scope for independent users of the struct tag. The tags `required:"true"` and `validate:"required"` do not follow this convention.

The tag should be something like `binding:"required"`.  

Message has been deleted

Matthew Holt

unread,
Dec 14, 2013, 12:36:40 PM12/14/13
to golan...@googlegroups.com
Definitely considered it. We talked at length about how to implement the required indicator. The problem is that "form" is only one way to bind (it could also be JSON which uses the encoding/json package). We want the required indicator to be universal no matter how the request was received.

On Saturday, December 14, 2013 10:28:41 AM UTC-7, Islan Dberry wrote:
On Saturday, December 14, 2013 9:16:05 AM UTC-8, Islan Dberry wrote:
The tag should be something like `binding:"required"`.  

If I understand the code correctly, you are already using the "form" key.  You should do something like:

   Title string `form:"title,required"`   // name=title, required = true
   Foo string `form:",required"`  // name=Foo, required=true
   Bar string `form:"bar"` // name=bar, required=false

Ian Lance Taylor

unread,
Dec 14, 2013, 1:28:22 PM12/14/13
to Matthew Holt, golang-nuts
On Sat, Dec 14, 2013 at 8:04 AM, Matthew Holt <matthe...@gmail.com> wrote:
>
> I'm thinking of something similar to accessing map keys:
>
> value, ok := someMap[key]
>
> Where `ok` is true or false, depending on if the key exists in the map. This
> is tremendously helpful.
>
> Similarly, I think it would be really convenient to know if a struct field
> tag exists, even if its value is "". I'm talking about this function:
> http://golang.org/pkg/reflect/#StructTag.Get
>
> For instance, to mark a field as required for Martini, you have a field tag
> like this:
>
> type BlogPost struct {
> Title string `form:"title" json:"title" required`
>
> Notice "required" is tacked on at the end. This doesn't break the existing
> implementation of the tag parser, but it would be nice to know if the
> "required" tag exists, even if its value is empty string "":
>
> tagValue, ok := structField.Get("required");
>
> I realize this is not necessarily backward-compatible, so what about a new
> function on StructField like .Tag() or .Has() or something?

I don't see a persuasive reason for this. StructTag.Get is for the
convention described at http://golang.org/pkg/reflect/#StructTag. You
are describing a slightly different convention. You can write a
decoder for your convention easily enough, but I don't see a strong
reason to change the way the existing one works.

Ian

Matthew Holt

unread,
Dec 14, 2013, 1:32:42 PM12/14/13
to golan...@googlegroups.com, Matthew Holt
Mostly, it would be so that we can use valueless keys in tags where it makes sense without breaking the existing "Get" method.

But the convention of the package name being the key also has merit.

Currently, valueless keys break the "Get" method on StructTag, unless it's at the end. Would it be worth making "Get" more robust to handle the case where a key without a value is found? Right now the behavior is undefined. This would let other authors use struct tags more liberally without changing the standard convention.

For what it's worth, the binding package in martini-contrib has already been altered to conform to the convention.

Rob Pike

unread,
Dec 14, 2013, 2:11:52 PM12/14/13
to Matthew Holt, golan...@googlegroups.com
Instead of changing the standard to match your convention, change your
convention to match the standard.

-rob

Matthew Holt

unread,
Dec 14, 2013, 2:12:54 PM12/14/13
to Rob Pike, golan...@googlegroups.com
Yup, done.
--
PRIVACY NOTICE: Do not include me in mailings when my private address is visible to all the recipients. Please send the email separately or use BCC instead.

Naitik Shah

unread,
Dec 25, 2013, 4:37:45 AM12/25/13
to Matthew Holt, golan...@googlegroups.com
If you still want it: http://godoc.org/github.com/ParsePlatform/go.structtag
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.



--
-Naitik
Reply all
Reply to author
Forward
0 new messages