[Follow us to learn Golang] infrastructure

Time:2019-10-9

In view of the installation of the Go language environment we talked about in the previous article, we now have an environment that can run the Go program, and we ran’Hello World’and ran out of our first Go program.
In this section, we will take’Hello World’as an example to explain the infrastructure of Go and explain in detail what each line in Hello World represents.

The Go language is a static language. Before compiling, the code will be strictly checked for grammar. If the grammar errors are not compiled, the infrastructure is a very important link.

<!–more–>

Similar to package, class, interface, function, constant and variable in Java, Go also has package, struct, interface, func, constant, variable and so on.

Strct, like class in Java, is the basic structure of Go.
Interface is also similar to the interface in Java, which defines functions for other struct or func implementations (which may not be well understood, as I’ll talk about later).

Here we will explain it in the order from outside to inside and from top to bottom.

GOPATH

As mentioned in the previous section, GOPATH specifies the file path to store the project. The following directories include’bin’,’pkg’,’src’.

1. SRC stores project source code

2. PKG stores compiled files

3. bin stores executable files generated after compilation

The directory structure is as follows

GOPATH
    \_ src
        \_ projectA
        \_ projectB
    \_ pkg
        \_ projectA
        \_ projectB
    \_ bin
        \_ commandA
        \_ commandB

The SRC directory is the one we use most, because all of our projects will be placed in this directory. References to subsequent projects are also relative to the directory.

file name

A Go file, our first understanding of it, is its suffix, Go file with‘.go’It’s easy to understand the end (the problem that Windows users must have file suffixes).
It’s also very easy to understand languages that don’t start with numbers, can’t contain operators, can’t use Go keywords, and so on.
A valid identifier must begin with a letter (any UTF-8-encoded character or) with any number or character, such as `hello_world.go’, `router.go’, `base58.go’, etc.

Go Natural Support UTF8

However, there are some details to note here, that is, when the Go file is named, it is different from other languages.
Go files are named in lowercase letters (although capitalization is also supported, but capitalization filenames are not standardized). If multiple words are needed for splicing, the words are named in lowercase letters (capitalization is also supported, but capitalization filenames are not standardized)._Underline the connection.
Especially the naming of Go files when writing test cases and multi-platform support.
Such as:’math_test.go’,’cpu_arm.go’,’cpu_x86.go’, etc.

Naming specification

Go can be said to be very clean and tidy code, so the name of Go is very concise and meaningful. Although it supports case-mixing and underscored naming, it’s really very irregular, and Gos doesn’t recommend it. Go prefers hump naming. Definitions like’Block Height’and’txHash’. In addition, the definition of Go can be used directly through the way of’package. Xxx’, so it is not recommended to use the definition of GetXXX.

package

Packet exists to solve the problem of confusion caused by too many files. It is always uncomfortable to see too many files in the project root directory, which is a problem for development and later maintenance.

As one of the ways to structure code, every Go program has the concept of package.

Go Grammar Provisions

  1. The first line of each Go file (without comments) must be the definition of package
  2. An executable program package definition must bemain
  3. Package defaults to the name of the current folder and does not use cascading definitions similar to packages in Java

The following code specifies that the file belongs to the learning_go package.

package learning_go

...

The definition of “Go” is not strict. A “Go” file under a folder may not use the folder name as the definition of “package” (default), but all “Go” files under the same folder must use the same package definition, which is strictly required.

Tips: Package should be defined in lowercase letters, so folders should also be defined in lowercase letters.

In order to better distinguish different projects, the project structure defined by Go contains information about open source sites, such as github, gitee and other open source sites, all open source Go projects can be directly used.

Behind Go is all the open source world.

Take the GoGoGoGoProject gosample project created under GitHub as an example. Its project path is “github.com/souyunkutech/gosample”. “Github.com” represents its open source site information. “Souyunkutech / gosample” is the name of the project.
The path of the file corresponds to “$GOPATH/src/github.com/souyunkutech/gosample”.

“Souyunkutech” means that the gosample project belongs to the user “souyunkutech”.

Acquisition of package

Before referring to an item, you need to get its source code and place it in$GOPATH/srcNext, we can refer to it and compile it correctly.

Getting the source code from Go can either manually place the source code in the correct path according to its relative path, or throughgo get pathThe method of automatic acquisition.

For example, if you get the’gosample’project, you cangit cloneHow to download to$GOPATH/src/github.com/souyunkutech/

It can also be passed throughgo get github.com/souyunkutech/gosampThe way to get it, go will bring the project to you$GOPATH/src/github.com/sirupsen/Under the catalogue.

If you get logrus, a well-known third-party log component in the Go language, you can pass it throughgit cloneHow to download to$GOPATH/src/github.com/sirupsen/

It can also be passed throughgo get github.com/sirupsen/logrusThe way of acquisition.

Reference to package

The import keyword serves as a reference to the package. As the smallest unit of external reference, Go is based on packages, unlike Java, which is based on objects for other programs to refer to. Import refers to a package that refers to all (visible) content of the package.

Grammatically, it is important to note that double quotation marks are needed to wrap references. Unused package references are either deleted or defined as implicit references. Otherwise, errors will be reported when running or compiling the program:imported and not used:…

For example,’fmt’referred to in HelloWorld code is a built-in program package in the Go language. FMT This package contains’doc. go’,’format. go’, etc. (which can be viewed by IDE) All the (visible) content in these Go files can be used.

As mentioned earlier, import references are by default relative to$GOPATH/srcCatalogue. So if we want to use an open source project, we need to use it relative toGOPATH/srcRelative paths are referenced. (Except for projects built into the Go system)

There are two ways to refer to the syntax of import

Mode 1, default reference mode, each reference occupies a single line, such as:

import "fmt"

Mode 2: Write all references in one import in parentheses, with each reference taking up a single line. In this way, Go formats all references in alphabetical order, so it looks particularly clear. For example:

import (
        "fmt"
        "math"
    )

For example, the logrus project structure is‘github.com/sirupsen/logrus’So when you refer to this log component, write the following

import "github.com/sirupsen/logrus"

If you want to use only one package in a logrus project, you can refer to the package alone instead of the logrus project as a whole. This is also very convenient.
For example, to use’hook / syslog / syslog. go’in the logrus project, you can write import as follows

import "github.com/sirupsen/logrus/hooks/syslog"

The reference to Go also supports file paths. When’. / utils’refers to util package in the current directory, it can be written as follows. Of course, it is the most appropriate and standardized way to write according to the project path. It is not recommended to use file path for reference.

import "./utils"

Implicit citation

A particular alternative support for Go references is implicit references, which need to be preceded by references._Underline identification. This type of reference typically occurs when loading a database driver. For example, when loading MySQL database driver. Because these drivers are not directly used in the project, but not referenced. So it’s called implicit reference.

import _ "github.com/go-sql-driver/mysql"

Packet referencing process needs to be careful not to refer to two identical projects at the same time, that is, no matter the site of the project and the project belongs to, as long as the reference project package name is the same, it is not allowed, when compiled, it will prompt’XXX redeclared as imported package name’error. Except for implicit references.

import "encoding/json"
Import "github.com/gin-gonic/gin/json"//!!! No!!!

But whether it can be used depends on the visibility of the package.

visibility

Visible rows can be understood as private and public in Java. Structures, structure fields, constants, variables, and functions in capital letters are externally visible and can be referenced by external packages. For example, the “Println” function in “fmt” can be quoted by other packages in capitalization, and the “free” function in “fmt” can not be quoted by other packages in lowercase.

However, regardless of whether the external package is visible or not, all definitions under the same package are visible and can be referenced and used.

function

In the Go language, functions are used most frequently. After all, code should be written clearly and easily. It seems that all programming languages have the concept of functions (no language has heard of the concept of functions at present).

In Go, the definition of a function supports multiple parameters, as well as multiple return values (more powerful than Java), which are separated by English commas.

Similar to Java, Go’s function body uses‘{}’Brackets wrap, but the definition of Go is more stringent. Go requires that the left bracket'{‘must be in line with the function definition, otherwise it will report an error:’build-error: syntax error: unexpected semicolon or new line before {‘.

  • Function Definition of Multiple Parameters
func methodName(param1 type, param type2, param type3){
    ...
}

// In short, you can define the same type of parameters side by side
func methodName(param1, param2 type, param3 type2) {
    ...
}
  • Function Definition with Return Value

The definition of the return value of a function can only define the return type or directly define the returned object.

After defining the returned object, the definition can be used directly within the function, avoiding the problem of defining variables multiple times in the function. At the same time, when returning, you can simply use a’return’keyword instead of a’return flag’ return statement.
It is important to note that either the return value defines the return object or not, and Go does not allow defining only part of the function return object.

// The simplest function definition
func methodName(){
    ...
}

// Define only the type returned
func methodName() bool{
    ...
    
    return false
}


// Define the object + type returned
func methodName() (flag bool){
    ...

    return
}

// Define multiple return types
func methodName()(bool, int) {
    ...
    
    return false, 0
}

// Define multiple return objects + types
func methodName()(flag bool, index int) {
    ...

    return
}

//!!!! Definition not allowed!!!
func methodName()(bool, index int){
    ...
    
    return
}

//!!!! Definition not allowed!!!
func methodName()
{
    ...
        
    return
}

There are two special functions in Go, the’main’function and the’init’ function.

The’main’function is the main entry to the program, and the package main must contain the function, otherwise it will not run. In other packages, the energy of the function is a normal function. Special attention should be paid to this point.
It is defined as follows, without or without any parameters and return values.

func main(){
    ...
}

The’init’function is the initialization function of the package, which is executed before the’main’ function is executed.

The same package can contain multiple init functions, but the execution order of multiple init functions Go does not give a clear definition, and for later maintenance is not convenient, so it is more appropriate to define only one init function in a package as far as possible.

The init function in multiple packages is executed in the imported order. The init function of the imported package is executed first. If multiple packages refer to a package at the same time, it will only be imported once, and its init function will only be executed once.

Its definition is the same as main function, and it does not and cannot take any parameters and return values.

func init(){
    ...
}

data type

In Go, there are

  • Basic types: int (integer), float (floating point), bool (bool), string (string type)
  • Collection types: array (array), slice (slice), map (map), channel (channel)
  • Custom types: struct (structure), func (function), etc.
  • Pointer type

The collection type of Go is not as complex as Java, and there are no thread-safe and orderly collections (all need to implement ^____________).

Both array and slice collections are similar to arrays in Java, and they are the same in use. So often I forget what the difference is between them. Actually, it’s very detailed. Array has length, slice has no length. The difference between them is so small.

Channel is a unique set of Gos, and is the core content of concurrency in Gos. Pipelines in Unix are also very similar.

The struct structure is simply understood as the object, and it can define its own object for structured use. Unlike classes in Java, functions in Java are written in classes. In Go, struct functions are written outside of struct.
Structural definitions need to be defined using type keywords combined with struct. The field before the struct is the name of the new structure. Internal fields can be set to be visible to the outside at the beginning of capital letters, or to be invisible to the outside at the beginning of lowercase letters. The format is as follows:

type Student struct {
    Name     string
    age      int
    classId  int
}

func main(){
    Var student Student = Student {Name: Xiaoming, age: 18, classId: 1}
    Fmt. Printf ("Student Information: Student Name:% s, Student Age:% d, Student Class Number:% d", Student. Name, Student. age, Student. classId)
}

For structures, Go also supports the following definitions

type MyInt int

This is a custom int type. The purpose of this is that MyInt not only contains the features of the existing int, but also adds the functions you need on top of it. This involves the high-level grammar of the structure, which we will introduce in detail later.

The author of Go has designed C language before. Maybe that’s why Go has pointer type too. But really, pointers in Go are much better understood than pointers in C. Simply precede the type when defining*The asterisk is OK. It is normally used without the need for an asterisk. The assignment to it needs to be used&Copy its address to the pointer field.

var log *logrus.Logger

func init(){
    log = logrus.New()
}

func main(){
    log.Println("hello world")
}

There are many types of content. Different types have different contexts in terms of definition and use, which will be introduced in the future. Today I will introduce the definition of type.

In Go, the definition grammar is the same for both constants and variables.

Constant definitions use const keywords, support implicit definitions, and can also be defined at the same time for multiple constants.

Const PI float = 3.1415926//explicit definition
Const SIZE = 10 // Implicit Definition
// Simultaneous definition of multiple constants
const (
    LENGTH = 20
    WIDTH = 15
    HEIGHT = 20
)

// Simultaneous Definition of Constants in Another Writing
Const ADDRESS, STREET = "Wangjing SOHO, Chaoyang District, Beijing", "No. 1 Wangjing Street"

Variable definitions use VaR keywords, which also support implicit definitions and simultaneous definitions of multiple variables.

var word = "hello"
var size int = 10

var (
    length = 20
    width = 15
    height = 20
)

Var address, street = Wangjing SOHO, Chaoyang District, Beijing, No. 1 Wangjing Street

Go also supports the combination of declaration and assignment in one step when defining variables. As follows:

 size := length * width * height

This saves the step of defining variables and makes the code more concise and clear. It is a recommended method. (Constants can’t be used like this.)

Keyword and Retained Word

In order to ensure the conciseness of the Go language, keywords are also very few in design, only 25.

break case chan const continue
default defer else fallthrough for
func go goto if import
interface map package range return
select struct switch type var

Of course, in addition to keywords, Go also retains some basic types of names, built-in function names as identifiers, a total of 36.

append bool byte cap close complex
complex64 complex128 copy false float32 float64
imag int int8 int16 int32 int64
iota len make new nil panic
print println real recover string true
uint16 uint32 uint64 uint uint8 uintptr

In addition,_Underlines are also a special identifier, called a blank identifier. So he can receive declarations and assignments of variables like other identifiers. But his role is special, to discard unwanted assignments, so use_Underlines declare values that are not available in subsequent code, and of course cannot be paid to other values, nor can they be calculated. These variables are also collectively referred to as anonymous variables.

summary

So far, this article explains package, func and type in Go. These three parts constitute the basic structure of Go language. At this point, we can also have a clear understanding of Hello World’s code. You can also try to write a simple example to deepen your impression. Following is a program implemented by using basic structures such as variables, constants, and functions, which can be understood by reference. The source code can be obtained through’github.com/souyunkutech/gosample’.

// Source path: github.com/souyunkutech/gosample/chapter3/main.go
Package main // Define package as main to execute the following main function, because main function can only be executed in package main

// Brief version of import import dependent project
import (
    "Fmt" // Use the Println function below it
    "Os" // Use the Stdout Constant Definition below
    Definition of RFC3339 using time format constants under time package

    "Github.com/sirupsen/logrus"//log component
    "Github.com/souyunkutech/gosample/util"//toolkit written by oneself, below is a unified use of custom functions
)

// Declare that the log variable is the pointer type of logrus. Logger and does not require pointers when used
var log *logrus.Logger

// Initialization function, prior to main function
func init() {
    Log = logrus. New ()/// Initialization of logrus components using the New () function under the logrus package
    Log. Level = logrus. DebugLevel /// Set the Level field in the log variable to DebugLevel under logrus
    log.Out = os.Stdout
    Log. Formatter = & & logrus. TextFormatter {// Because log. Formatter is declared as a pointer type, assignment to it also requires the'&'keyword to assign its address to the field.
        TimestampFormat: time. RFC3339, // Use the RFC3339 constant under the time package. When assigning, if the field and braces are not in the same line, you need to add commas after the assignment, including the assignment of the last field!!!
    }
}

// Define constant PI
const PI = 3.1415926

// Define Student Architecture, which can be used to unify student information.
type Student struct {
    Name string // Name visible to the outside (capital letters)
    Age int // Age can't be easily known, so it's invisible to the outside world.
    ClassId int // Classes, too
}

// main function, entry to program execution
func main() {
    Var Hello = Hello world /// Defines Hello variables, omitting the declaration of its type string
    Println (hello)// Println functions under the FMT package are used to print Hello variables

    // Definition and assignment of multiple variables, generated using external functions
    Length, width, height: = util. RandomShape ()/// Functions using other packages

    // Multiple variables as parameters of external functions
    size := util.CalSize(length, width, height)
    Log. Infof ("length =% d, width =% d, height =% d, size =% d", length, width, height, size)// Print length, width and size using the function of logrus

    Var student = Student {Name:'Xiaoming', age: 18, classId: 1}// declares student information, and the assignment of the last field does not require a comma.
    Log. Debugf ("Student Information: Student Name:% s, Student Age:% d, Student Class Number:% d"), Student. Name, Student. age, Student. ClassId)/// Print Student Information Using Logrus Function
}

The results are as follows:

hello world
INFO[0000] length=10, width=15, height=20, size=3000
DEBU [0000] Student Information: Student Name: Xiaoming, Student Age: 18, Student Class Number: 1

If there is still something that we don’t understand, we can discuss it or leave a message through Search Cloud Technology Group, and we will answer it.

The source code can be obtained through’github.com/souyunkutech/gosample’.

Wechat Public Number

[Follow us to learn Golang] infrastructure

First Wechat Public Number: Go Technology Stack, ID: GoStack

Copyright belongs to the author, please contact the author for any reprint.

Author: Soyunku Technical Team
Origin: https://gostack.souyunku.com/…