Writing code for repetitive tasks like creating methods to validate custom types or turning those types into readable texts can be time-consuming and require significant effort for debugging and testing. To address this issue, Go provides a tool called stringer
.
stringer
toolThe stringer
tool is included in the golang.org/x/tools/cmd/stringer
package. It simplifies the process of generating string methods for custom types. String methods are functions in Go that implement the stringer
interface, specifically the String()
method. This method defines how a custom type should be converted to a readable format such as string representation. Instead of manually writing a String()
method for each value of a custom enum type, the stringer can automate this process.
When applied to a custom type, such as an enum-like type with defined constants, the stringer automatically generates an implementation of the String()
method. This tool reads the definition of the custom type and its constants and produces a Go source file with the String()
method implemented.
// Define a custom type with constantstype Day intconst (Sunday Day = iotaMondayTuesdayWednesdayThursdayFridaySaturday)// The stringer tool will automatically generate the String() method for this type, so you don't have to write it manually.
By utilizing the stringer
tool, developers can save time and effort that would otherwise be spent manually writing and maintaining string methods for their custom types. This leads to improved code quality, reduced chances of errors, and enhanced code maintainability.
Suppose we have to validate the type of file and want to accept two types of files; Flat
or Zip
. There are two ways to do this; firstly write custom validation code manually, and secondly use stringer
tool. Here we use stringer
.
The first step is to configure the environment in your system to run stringer
:
go get golang.org/x/tools/cmd/stringer@latest
Set the PATH
to access the stringer
tool:
export PATH="$PATH:/Users/<Username>/go/bin"
<Username>
will be according to your system.
Create custom type:
package srctype FileType intconst (FlatType FileType = iotaZipType)func ParseFileType(input string) FileType {switch input {case FlatType.String():return FlatTypecase ZipType.String():return ZipTypedefault:return -1 // Invalid file type}}
Line 3: We create a custom type FileType
.
Lines 5–8: We define enums for FlatType
and ZipType
.
Lines 10–19: We define a ParseFileType
which validates our input string based on the String()
method that will be generated by the stringer
tool.
To use the stringer
tool, we have two methods; using the command line or using comments to generate Go. Here, we will discuss both:
To generate code using comments, we need to add the line 3 in our code. In this line go:generate
is Go tool chain that tells the Go compiler to execute the command followed by generate
keyword (stringer -type-FileType
in our case):
package src//go:generate stringer -type=FileTypetype FileType intconst (FlatType FileType = iotaZipType)func ParseFileType(input string) FileType {switch input {case FlatType.String():return FlatTypecase ZipType.String():return ZipTypedefault:return -1 // Invalid file type}}
To generate code using comments that we inserted in our code, run the following command in the terminal:
go generate <path to the file>
In the above command, <path to file>
is the file in which we add comments for stringer
command.
If we do not want to add comments like in line 3 in the above code. We can directly run stringer
by ourselves using a terminal like below:
stringer -type=<custom type> <path to file.go>
stringer
is the command that we set up in steps 1 and 2.
-type=<custom type>
in this flag type
is a keyword that specifies the type that we want to create and <custom type>
is the name of our type, FileType
in our case.
<path to file.go>
is the path where we define the structure for custom type. It can be an absolute or relative path but it must include the file name at the last.
Both methods will generate the same following output code:
// Code generated by "stringer -type=FileType"; DO NOT EDIT.package srcimport "strconv"func _() {// An "invalid array index" compiler error signifies that the constant values have changed.// Re-run the stringer command to generate them again.var x [1]struct{}_ = x[FlatType-0]_ = x[ZipType-1]}const _FileType_name = "FlatTypeZipType"var _FileType_index = [...]uint8{0, 8, 15}func (i FileType) String() string {if i < 0 || i >= FileType(len(_FileType_index)-1) {return "FileType(" + strconv.FormatInt(int64(i), 10) + ")"}return _FileType_name[_FileType_index[i]:_FileType_index[i+1]]}
To test the code, click the “Run” button and execute the below commands in the terminal:
Note: To use CLI method, you can remove the line 3 in the
file_type.go
.
# Command to run stringerstringer -type=FileType src/file_type.go# Command to generate codego generate ./...# Command to run codego run main.go# Command to list the file inside the src folderls src# Command to move into src directorycd src# Command to open the filecat filetype_string.go
module stringer go 1.23
By leveraging stringer
, developers can save time and effort that would otherwise be spent on manual implementation and maintenance of string methods. Both methods achieve the same result, generating the necessary code for string methods. This not only improves code quality but also enhances maintainability and reduces the risk of bugs.
Free Resources