This is a creation in Article, where the information may have evolved or changed.
Seven go language tips, followed by continuous updates.
Whether it's a small go language or an experienced developer, it's possible to get inspiration from it.
A word of skill
- Throw your object-oriented brain into your home and embrace the interface. @mikegehard
- Learn how to do things with go, and don't force other programming styles into go. @DrNic
- The multi-use interface is always better than less. @evanphx
- Embrace this concise, parallel, neat language. @francesc
- It's great to read all the documents on the official website golang.org. @vbatts
- Don't forget to use it
gofmt
. @darkhelmetlive
- Read the source code more. @DrNic
- Learn the tools and components and then create your own! Code codes and learning code are essential to success. @coreyprak
- Learning without thinking is not the case, but thinking without learning is dangerous. Analects
Multiple ways to introduce a package
There are several unconventional ways to introduce packages. Next I'll use it fmt
as an example:
import format "fmt"
-to fmt
create an alias. Replace all the used content in fmt
the code format.
fmt.
import . "fmt"
-Allow content inside the package to be fmt
directly referenced without prefix
import _ "fmt"
-Prevents the compiler from prompting for the introduction of fmt
content without using it, and executes the initialization function in the package. A reminder that in this case fmt
is not callable
Check out this blog for more details.
Goimports
Command goimports
to update your go import row, add missing rows, and delete unreferenced boot lines.
It has gofmt
the same capabilities as (plug-in substitution), but goimports
adds additional functionality to repair imports.
Organization
Go is a relatively easy-to-learn programming language, but for developers, the most difficult thing to do with the language at first is how to organize the code. scaffolding
is one of Rails
the reasons people like it, it can give new developers clear direction, let them understand where to insert code, should follow what kind of programming style.
As an extension, go uses go fmt
such tools to provide the same functionality as developers. In the same way, the go compiler is very strict and does not compile unused variables or import declarations that are not used.
Custom constructors
I often hear people ask, "When should I use a custom constructor like newjob
?" "In most cases you don't need to do that," my answer is. However, when you need to set the value at initialization and you have some default values, it is best to use a constructor. In this example, the constructor is more meaningful, so we can build a default logger with the following code:
12345678910111213141516171819 |
package mainimport ( "log" "OS" ) type Job struct {Command span class= "keyword" >string *log. Logger}func newjob (command string ) *job {return &job{command, log. New (OS. Stderr, , log. Ldate)}}func main () {newjob (). Print ( "Starting now ..." )} |
Break down the code into different package
Refer to this blog to refactor the Go code, the first part is about the organization of the package.
In engineering Gobot
, for example, it can be split into a core package and some other package. Gobot's developers prepare each part in their own package. After discussion, they chose to put all the official libraries under the same repository, making the import path clean and logical.
So, they're not going to set the path to:
123 |
Github.com/hybridgroup/gobotgithub.com/hybridgroup/gobot-spherogithub.com/hybridgroup/gobot-... |
Instead, set to
123 |
Github.com/hybridgroup/gobotgithub.com/hybridgroup/gobot/spherogithub.com/hybridgroup/gobot/... |
Now the name of the package is no longer a lengthy gobot-sphero, and it becomes a brief sphero.
Collection (sets)
In other programming languages, there is often a data structure called sets, which allows the elements to be deposited, but not allowed to be duplicated. Go does not directly support this structure, but the implementation of this structure in go is not difficult.
1234567891011121314151617 |
// UNIQSTR returns a copy if the passed slice with only unique string results. func uniqstr string ) []string {m: = map [string ]struct {}{}for _, V: = Range Col {if _, OK: = M[v];!ok {M[v] = struct {{}}} List: = make ([]string , len (M)) I: = 0 for V: = range m {list[i] = vi++}return list} |
Playground links
Here, I will use some very interesting tricks. First, the mapping of the empty structure:
1 |
Map [string] struct {}{} |
We created one map
, which ensures that it key
is unique, and that it is related to value
what we do not care about.
We can of course use:
However, using an empty structure can achieve the same efficiency without consuming additional memory.
The second gimmick is more profound:
123 |
if _, OK: = M[v];!ok { struct{} {}} |
The thing to do here is to make sure that m
a value in the map exists and doesn't care about value
itself. If no corresponding value is found, add one. Of course, not to verify the direct addition seems to be no different.
Once we have a map full of unique keys, we can put them in a slice and return the results.
Here's a test code, as you can see, here's a table test that matches the Go Language Unit test style:
1234567891011121314151617181920 |
func testuniqstr(t *testing. T) {data: = []struct{in, out []string}{{[]string{}, []string{}},{[]string{"","",""}, []string{""}},{[]string{"a","a"}, []string{"a"}},{[]string{"a","B","a"}, []string{"a","B"}},{[]string{"a","B","a","B"}, []string{"a","B"}},{[]string{"a","B","B","a","B"}, []string{"a","B"}},{[]string{"a","a","B","B","a","B"}, []string{"a","B"}},{[]string{"a","B","C","a","B","C"}, []string{"a","B","C"}},} for_, Exp: =RangeData {res: = Uniqstr (exp.in)if!reflect. Deepequal (res, exp.out) {t.fatalf ("%q didn ' t match%q\n", res, Exp.out)}}} |
The test found that not every time can be successful, but there is a probability. Because the map is implemented using HASHMAP, it is possible for this test to fail because the traversal order of the string does not necessarily relate to the contents of the strings when it is traversed using range. A similar error may occur when Deapequal is performed ["b" "c" "a"] didn't match ["a" "b" "c"]
. Of course, in playground, the context of each execution is exactly the same, so the test here is always passed.
Dependent package Management
Unfortunately, the official go language does not provide a dependency package management system. This is probably because the go language is rooted in the C language culture, so it has no way to introduce a specific version of the package.
This can lead to some serious problems:
- When multiple developers work together to maintain a project, the dependent versions of different developers may be different.
- Dependencies also have their own dependencies, so it is difficult to ensure that all dependencies use the same version.
- Your multiple projects are based on a different version of the same dependency.
The last case can be solved by building a continuous integration environment (continuousintegration) , but the first two are relatively difficult.
Reference documents
- GO bootcamp-everything need to know-get started with go:tips and Tricks
- Analects
- Refactoring Go Code
- Alternate Ways of importing Packages