Sometime structs are defined with mutlti tags, and long then 100 or 120 columns.
The code can be formated pretty if struct tag support spliting with blank or "\n" or "\t".
// Current record struct
type Current struct {
ID int32 `db:"id,type=INT,auto_increment,key" binding:"gte=0" json:"id,omitempty" form:"id" uri:"id"`
Flag int32 `db:"flag,type=INT,not_null,primary" binding:"gte=0" json:"flag,omitempty" form:"flag"`
OS string `db:"OS,type=VARCHAR(16),not_null,primary" binding:"omitempty,oneof=AND IPH" json:"OS,omitempty" form:"OS" example:"AND"`
// ......
}
// Expect record struct, supporting one tag each line
type Expect struct {
ID int32 `db:"id,type=INT,auto_increment,key"
binding:"gte=0"
json:"id,omitempty"
form:"id"
uri:"id"`
Flag int32 `db:"flag,type=INT,not_null,primary"
binding:"gte=0"
json:"flag,omitempty"
form:"flag"`
OS string `db:"OS,type=VARCHAR(16),not_null,primary"
binding:"omitempty,oneof=AND IPH"
json:"OS,omitempty"
form:"OS"
example:"AND"`
// ......
}
each tag value can get by parsing the sub string in "" part after key:
similar with issue: #15893, but here: newline supporting between tags.
Thanks. I turned this into a proposal.
Although now that I've done that, I see that this is basically the same as #15893, which you mentioned. What is the difference between this proposal and that one?
Although now that I've done that, I see that this is basically the same as #15893, which you mentioned. What is the difference between this proposal and that one?
In general I like the implicit backpressure that the single-line requirement imposes: it keeps these things from turning into arbitrary pages-long annotation texts. I am not convinced we really want to open that door. The examples in the top comment are right at the limit of what seems reasonable.
If we did allow multiline strings I guess gofmt would need to adjust the indentation of the continuation lines when it adjusts the padding of fields?
Ultimately this comes down to a judgement call, not really a cost-benefit. But there is a real benefit to pushing back on such long struct tags - they persist at runtime in the binary, and they complicate trying to understand the program.
Most uses of struct tags in the Go ecosystem are very short. Personally, I still believe that we should not encourage them to be very long, nor make that easier.
We definitely _cannot_ make gofmt align the multiline formatting (inserting or removing spaces inside the backquoted string), by the way, because in general gofmt can't be sure about the interpretation of these strings.
/cc @myitcv @ianthehat @mvdan for more tools experience in this discussion.
(Please feel free to cc more people.)
I agree with the last comment. Multiline string literals can also easily make struct types confusing or less readable, as there wouldn't be an indentation/format style that could be enforced.
I think Go wouldn't have used a string literal for tags if they wanted tags to support complex data. It's really meant for a few simple attributes. If we really wanted we could add syntax for structural tags, akin to composite literals, but I imagine that would also encourage abusing tags for multiple purposes.
Spitballing alternatives, would it be reasonable to have multiple field tags? Then the compiler count combine them with " ". This would serve to simplify the alignment issues, since there is a way that these should be formatted/spaced, but would both change the syntax of the language, and probably make hell with the parser.
// Current record struct.
type Current struct {
ID int32 `db:"id,type=INT,auto_increment,key"` `binding:"gte=0"` `json:"id,omitempty"` `form:"id"` `uri:"id"`
Flag int32 `db:"flag,type=INT,not_null,primary"` `binding:"gte=0"` `json:"flag,omitempty"` `form:"flag"`
OS string `db:"OS,type=VARCHAR(16),not_null,primary"` `binding:"omitempty,oneof=AND IPH"` `json:"OS,omitempty"` `form:"OS"` `example:"AND"`
// ......
}
// Expect record struct, supporting one tag each line.
type Expect struct {
ID int32 `db:"id,type=INT,auto_increment,key"`
`binding:"gte=0"`
`json:"id,omitempty"`
`form:"id"`
`uri:"id"`
Flag int32 `db:"flag,type=INT,not_null,primary"`
`binding:"gte=0"`
`json:"flag,omitempty"`
`form:"flag"`
OS string `db:"OS,type=VARCHAR(16),not_null,primary"
`binding:"omitempty,oneof=AND IPH"`
`json:"OS,omitempty"`
`form:"OS"`
`example:"AND"`
// ......
}
@carnott-snap even if adjacent back-quoted strings were somehow combined, splitting them across lines would not work because there would be an implicit semicolon after each string-at-end-of-line.
(And you can't change the implicit semicolon after a string without breaking x = `a`.)
Thanks for adding your opinion @mvdan.
Based on the discussion above, this seems like a likely decline.
@carnott-snap even if adjacent back-quoted strings were somehow combined, splitting them across lines would not work because there would be an implicit semicolon after each string-at-end-of-line.
I am unclear how that invalidates the example, you could just update the parser to handle it. If your argument is that would be too expensive, then this becomes a readability vs parser elegance argument. If the lack of a block is troublesome, you could fix that too:
// Expect record struct, supporting one tag each line.
type Expect struct {
ID int32 {
`db:"id,type=INT,auto_increment,key"`
`binding:"gte=0"`
`json:"id,omitempty"`
`form:"id"`
`uri:"id"`
}
Flag int32 {
`db:"flag,type=INT,not_null,primary"`
`binding:"gte=0"`
`json:"flag,omitempty"`
`form:"flag"`
}
OS string {
`db:"OS,type=VARCHAR(16),not_null,primary"
`binding:"omitempty,oneof=AND IPH"`
`json:"OS,omitempty"`
`form:"OS"`
`example:"AND"`
}
// ......
}
@carnott-snap the rules for semicolon injection are part of the syntax, declared in the spec. Changing them isn't just about updating one parser or lexer. All Go developers have to adapt to the new rules, tools have to be fixed and updated, etc.
It is indeed possible to propose changes to the Go language, but the bar for them is high, and you must fill a template to provide enough information for the reviewers: https://github.com/golang/proposal/blob/master/go2-language-changes.md
I am not suggesting that the semicolons be removed, but that the parser understand that these are equivalent:
one int32 `db:"id,type=INT,auto_increment,key"` `binding:"gte=0"` `json:"id,omitempty"` `form:"id"` `uri:"id"``
two int32 `db:"id,type=INT,auto_increment,key"`; `binding:"gte=0"`; `json:"id,omitempty"`; `form:"id"`; `uri:"id"`
That is still a language change, since that syntax is not valid today.
Noting to add beyond @rsc and @mvdan's comments.
There's no change in the consensus since the last week. Declined.
Most helpful comment
@carnott-snap even if adjacent back-quoted strings were somehow combined, splitting them across lines would not work because there would be an implicit semicolon after each string-at-end-of-line.
(And you can't change the implicit semicolon after a string without breaking
x = `a`.)Thanks for adding your opinion @mvdan.
Based on the discussion above, this seems like a likely decline.