Go language AST Try

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

# Go Language ast Try

Go language has a lot of tools, goimports for the package automatic import or deletion, Golint used to check the source code does not conform to the go coding style, such as the full name, comments and so on. There are other tools such as Gorename, Guru and other tools. As tools they are all developed using the Go Language (https://github.com/golang/tools/tree/master/cmd), which have one thing in common: reading the source code, parsing the source code, modifying or generating new code.

# # Overview

Many programming languages/libraries/frameworks can generate code, for example, using rails, it's easy to get new project out and build the code for the program, which is boilerplate, or template. Dynamic languages like Ruby can often generate code at run time, which we call Meta programming (metaprogramming), such as rails ' resources to generate restful router. Because it is dynamically generated at run time, As a result, you may experience exception and loss of performance.

The macro of a programming language like Elixir is a "front" step in Ruby's meta-programming, which generates code at compile time rather than run-time, with the benefit of generating a large amount of code that has little effect on performance. Like the router ([view] (https://github.com/phoenixframework/phoenix/blob/master/lib/phoenix/router.ex#L375)) section of the Phoenix frame, A large number of functions are generated through macro, which is efficiently routed using beam's efficient pattern matching mechanism. The macro of Elixir is written in the source code, while go can be separated.

The go language can also generate code (such as creating objects) through the reflect package as well as Ruby's runtime, but even more powerful is that it generates new code by reading the source and then modifying the source. We can write this process alone with a tool that can be applied to different projects.


# # example

# # # [Stringer] (Https://github.com/golang/tools/tree/master/cmd/stringer)
```
Package Game

Go:generate Stringer-type=gamestatus
Note//With go:generate characters cannot have spaces between them
GameStatus indicate the state of the game
Type GameStatus int

Const (
Unvalid GameStatus = Iota
Validfailed
Valid
Register
Start
Running
End
)
```
Run ' go generate ' will generate the Gamestatus_stirng.go file and implement the Stringer interface.

The same example also appears in Grpc [code] (https://github.com/grpc/grpc-go/blob/master/codes/codes.go#L41), resulting in [string] (https:// GITHUB.COM/GRPC/GRPC-GO/BLOB/MASTER/CODES/CODE_STRING.GO).

As Rob Pike said:
> *let the Mechine do the work.*
> [Source] (Https://blog.golang.org/generate)


# # # [Gen_columns] (Https://github.com/qgymje/gen_columns)

Many projects use the database, through the tag to specify the name of the field in the database, when writing SQL, and only through the string to represent the field name, so if a field name modification, it means that the SQL involved in this field is faced with modification, and we want to modify only one place.

There is a structure as a database table structure as follows:
```
Type User struct {
ID int ' JSON: ' ID ' bson: ' id ' '
Name string ' JSON: ' Name ' Bson: ' Name ' '
}
```

When using the fields in this model for SQL queries, you typically use:

```
map[string]interface{}{
"id": 123456,
}

```

As a query condition, if the field name changes, you have to modify the key value in this map.
If you can automatically generate a struct to represent these column name values, you only need to modify one place:

```
map[string]interface{}{
usercolumns.id:123456
}
```

* How to use *
```
Gen_columns-tag= "Bson"-path= "./models/user.go"
```

Will generate a separate file with the following contents:
```
Package Models

Type _usercolumn struct {
ID string
Name string
}

var usercolumns _usercolumn

Func init () {
Usercolumns.id = "ID"
Usercolumns.name = "Name"

}
```

# # # Other examples
* [Impl] (HTTPS://GITHUB.COM/JOSHARIAN/IMPL) specifies an interface, the method required to generate the interface
* [Goa] (https://goa.design/) a set of DSL for writing Web service

Summary of # #
Gen_columns is the solution to the problem he has encountered in the project, the first version is done through reflect, a total of several steps required; With the AST you just need to add a go generate at compile time, and this command can basically be integrated in the build script, so you don't have to worry about code generation any more.
Let's use go to create more tools for generating code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.