Skip to content

proposal: Go 2: struct tag interpolation of constants #66108

Closed as not planned
Closed as not planned
@chad-bekmezian-snap

Description

@chad-bekmezian-snap

Go Programming Experience

Intermediate

Other Languages Experience

Python, JS, C#, Java

Related Idea

  • Has this idea, or one like it, been proposed before?
  • Does this affect error handling?
  • Is this about generics?
  • Is this change backward compatible? Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit

Has this idea, or one like it, been proposed before?

It feels like it must've before, but I couldn't find anything like it.

Does this affect error handling?

No.

Is this about generics?

No.

Proposal

Go supports adding tags to struct fields. This feature has been frequently used in packages used for ORMs, unmarshalling, code generation, struct validation, and more. It is not uncommon to see multiple values provided under a given tag, such as the json tag, or validate tag. These values are often separated by a literal comma, and an equals sign is generally used more or less as an assignment operator. A common convention is also to have the first value associated with a given tag define the name of the field within the context of that tag. Here is a somewhat overloaded example of such tags:

type User struct {
   Age int `json:"age,string" db:"age" validate:"required,min=18,max=30" doc:",desc=some helpful documentation"`
}

In the case of interacting with a database, I have also found myself on occasion declaring a constant with the name of the db column, for example:
const ColAge = "age"

Another semi-common pattern I have found is the use of a characters hex value to avoid issues with parsing struct tag values. For example:

struct {
   Field string `doc:",desc=this is a description, but it includes a comma and therefore isn't properly parsed"`
}

Commonly used struct tag parsing packages end up extracting the Field doc tag into three parts, due to the comma within the description. The offered solution is typically something along the lines of using the hex representation of a comma 0x2C, which would look like this:

struct {
   Field string `doc:",desc=this is a description0x2C but it includes a comma and therefore isn't properly parsed"`
}

I propose adding language support for interpolating constants into struct fields, which would hopefully improve readability, and reduce repetition. I don't have a desired exact syntax in mind, beyond of course that it would need to be backwards compatible. With the addition of this feature, the above examples could look something like this:

const (
   ColAge = "age"

   comma = "0x2C"
)

struct {
   Age string `db:"$ColAge" doc:",desc=this is a description$comma but it includes a comma and therefore isn't properly parsed"`
}

Language Spec Changes

No response

Informal Change

This change would allow interpolating constants in struct tags. Something like this:

const (
   ColAge = "age"

   comma = "0x2C"
)

struct {
   Age string `db:"$ColAge" doc:",desc=this is a description$comma but it includes a comma and therefore isn't properly parsed"`
}

Is this change backward compatible?

I believe it could be with careful consideration.

Orthogonality: How does this change interact or overlap with existing features?

The improvement would be in code readability.

Would this change make Go easier or harder to learn, and why?

It would be harder due to having another feature to learn, but the learning curve is minute.

Cost Description

A change to the compiler to handle the additional syntax. I am not super familiar with the compiler's implementation, but I expect it would be easy.

Changes to Go ToolChain

go

Performance Costs

the compile time cost would exist, but should be small

Prototype

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions