Some lessons from Golang’s development blog

During the National Day, I spent about 9 days rewriting the front desk part of the blog system with the help of Golang. Due to the particularity of the system, only 1/3 of the functions of the whole system could be completed after this part was completed. After coming back on October 11, I spent about 10 days writing a little every day to complete the remaining two parts of the system. Since this is the first time to use Golang to develop server content, so many pits, here is a summary.

Function transfer problem

This problem is not difficult, I noticed it when I first read the document, but I didn’t pay much attention to it. This problem is even more ignored because much of the logic code is copied from older Nodejs versions. I didn’t feel right until I learned that the local command took a little longer to execute.

Here’s a simple example:

package main

import (
	"fmt"
	"time"
)

func main() {
	_abc()
}

func _abc() {
	fmt.Println("start")
	starttime := time.Now()
	var data Tt
	for i := 0; i < 10000; i++ {
		Set(data)
	}
	fmt.Println(time.Since(starttime))

}

type Tt struct {
	Name     string
	Age      int
	Email    string
	Addr     string
	Nickname string
}

func Set(data Tt) Tt {
	data.Name = "ashan"
	data.Age = 32
	data.Email = "[email protected]"
	data.Addr = "china"
	data.Nickname = "ashan"
	return data
}
Copy the code

The above code takes about 214.323µs to run. This is done in 1ms, so let’s run it again with a few modifications to the code.

package main

import (
	"fmt"
	"time"
)

func main() {
	_abc()
}

func _abc() {
	fmt.Println("start")
	starttime := time.Now()
	var data Tt
	for i := 0; i < 10000; i++ {
		Set(&data)
	}
	fmt.Println(time.Since(starttime))

}

type Tt struct {
	Name     string
	Age      int
	Email    string
	Addr     string
	Nickname string
}

func Set(data *Tt) *Tt {
	data.Name = "ashan"
	data.Age = 32
	data.Email = "[email protected]"
	data.Addr = "china"
	data.Nickname = "ashan"
	return data
}

func Setint(data *int) *int {
	*data = 5 + 12*8
	return data
}
Copy the code

Running again takes about 50.675µs. The time difference is between four and five times.

This example tells us that the struct should try to pass a pointer when passing arguments to a function call. The reason is simple: if you do not pass a pointer, you will have its own scope inside the function. Because the scope is different, you will need to allocate memory space for the type passed in and create a copy of the same value. This operation is quite time-consuming.

In view of this problem, we can only reconstruct and modify, which has not been carried out at present, and will be adjusted when the next version is optimized and reconstructed.

Import cycle not allowed problem

This problem arose at the end of the project, when it was very strange to see why the “circular reference” problem had occurred, and it turned out to be caused by the import package loading mechanism of Goalng.

Import package B from package A and import package A from package B. When compiling, cross-recursive references occur, causing problems.

Think for a long time, so how to solve the problem will be better, the cause of this problem may appear in the following two situations:

  1. Use of stock in mutual application issues
  2. There are some problems in its module structure design

The first kind of problem basically belongs to drop pit, the solution method has no what good way, can only think of their own way to adjust.

The second case can be solved using refactoring, which is what I’ll be doing in the future. In this case, duplicate code can only be placed in a separate package as a common library to avoid such problems.

Uppercase and lowercase

Golang is a clever example of stinginess in syntax. In the design of external access permissions for functions, it does not even provide keywords such as public, and uses uppercase to distinguish between functions.

At first I envisioned all private access functions beginning with _. Looking at some implementations of the source code in Golang, I don’t have this habit. Just don’t do it that way. But a lot of times it’s easy to forget this rule, especially when I first started writing code directly with Sublime, and because there was no code prompt to install any plug-ins, case was often mixed up.

The problem with function calls is good, because compile time will tell you that the function you are calling does not exist. But turning structs into strings and querying data with MGO can produce empty results that can be extremely frustrating. At the same time, when struct is returned as the result of database query, the corresponding first letter of the field name must be capitalized, which is inconsistent with the case of the field in the database. This is also a minor problem.

memory

Here comes the platimous problem again. During the 20 days of golang contact and use, I did not pay much attention to memory control. At most, I was careful to open up variables.

conclusion

Overall, I was happy with the Golang, which sounded like a C. There are no major problems in the development of ideas.

enjoy!