Hi. In this post I’ll show how can get struct tag values in Golang. Firstly, very simple don’t be afraid.
Let’s start. Before starting, this post will show you reflection package’s a little part.
Import Reflection Package
import ( "fmt" "reflect" "strconv" )
Let’s suppose we have struct like this to create database columns. Our scenario is about ORM’s table generator:
// This table will generate automatically by our ORM. Just imagine it. type Employee struct { ID string <code>{{EJS0}}</code> Name string <code>{{EJS1}}</code> Surname string <code>{{EJS2}}</code> }
Our model is ready. But we still can’t create database table. Because there are no code blocks :).
Okay, we understood what will we do now. We need to struct tags and their values. As you know we imported reflected package.
Let’s initialize Employee struct.
e := Employee{}
After that we’ll need reflection package. For example:
e := Employee{} // c variable represents table columns c := reflect.TypeOf(e).Field(0).Tag
As I said, c variable represents the database columns we will create. If we try to print c variable we’ll see this output:
fmt.Printf("%s\n\n", c) //Output: auto_increment:"true" increment:"1"
Yes you know what’s the Field(0). Every struct field has index number in reflection package. We’ll call them by their numbers. That’s like arrays. Okay, we know our column has two properties. But we still don’t know how to parse struct tags? Don’t worry.
Parse Struct Tags
There are two ways to parse struct tags.
The Get() Method
e := Employee{} // c variable represents table columns c := reflect.TypeOf(e).Field(0).Tag //g variable represents get g := c.Get("increment") fmt.Printf("Get method: %s\n", g)
Above code will output this result: Get method: 1. That’s what we want. In some cases you will want to know tag is declared. For example tag isn’t declared you won’t get any error message or boolean result. If variable isn’t declared output will be empty. So, you can check like this:
if g == "" { // blah blah }
Okay. We know how to parse with Get method now. What about the other way?
Lookup Method
Firstly you should need to know Lookup and Get are different methods. As I said the Get method does not give any error message or boolean result.
Lookup method is different. Because if variable isn’t declared in the struct you can get boolean result. How?
e := Employee{} // c variable represents table columns c := reflect.TypeOf(e).Field(0).Tag //g variable represents get g := c.Get("increment") fmt.Printf("Get method: %s\n", g) // val variable represents tag value, ok variable represents true / false val, ok := c.Lookup("auto_increments") // ---> auto_increments isn't declared fmt.Printf("Lookup method: %s - %s", val, strconv.FormatBool(ok))
Above code will show this output: Lookup method: – false That’s what we want. Again I’ll say, in some cases you will want to know tag is declared. This is the best way to control more efficiently. For example:
if !ok { panic("Hey dude, the tag isn't there") } fmt.Printf("Lookup method: %s - %s", val, strconv.FormatBool(ok)) /* auto_increment:"true" increment:"1" Get method: panic: Hey dude, the variable isn't there goroutine 1 [running]: main.main() /tmp/sandbox622013167/main.go:25 +0x4a0 */
You’re program won’t work because of the tag isn’t there. You don’t have to use panic. If your data is important you should use panic method to avoid errors.
That’s all I can tell.