First, the basic situation
1.1. Basic introduction to Golang
The Go language, or Golang, began in 2007 and was officially released in 2009. Go is a very young language whose main goal is to “combine the speed of dynamic languages like Python with the performance and security of compiled languages like C/C++.”
The launch of Go language aims to reduce the complexity of the code without losing the performance of the application. IT has the advantages of “simple deployment, good concurrency, good language design, good execution performance” and so on. At present, many IT companies in China have adopted Go language for their development projects.
Go is sometimes described as a “C-like language,” or “C for the 21st century.” Go inherits similar expression syntax, control flow structure, basic data types, call parameter values, Pointers, and many other ideas from C, as well as the efficiency of compiled machine code and the seamless adaptation of existing operating systems that C has always looked at.
Because the Go language has no concept of classes or inheritance, it doesn’t look the same as Java or C++. But it implements polymorphism through the concept of interfaces. The Go language has a lightweight type system that is clear and easy to understand, and there is no hierarchy between types. So Go is a hybrid language.
In addition, many important open source projects have been developed using the Go language, including Docker, Go-Ethereum, Thrraform, and Kubernetes.
According to the latest Tiobe programming Language rankings for September 2020, Golang is currently ranked 11th in usage:
1.2 Golang Usage Scenarios
- Server-side development (with gin, GORM and other libraries to achieve high performance back-end services)
- Container development (for example, Docker, K8s are based on Golang)
- Scripting development (Golang can also be used as an alternative to Python because it is easy to deploy itself and interact with the operating system apis)
- Development of underlying tools (alternative to C or C++ for developing operating system underlying tools)
Second, basic grammar
2.1 coding protocol
Golang is a strict engineering language, mainly reflected in the coding style and visibility rules. In Java, multiple coding styles are allowed to coexist. For example, the following two method declarations are allowed for Java:
public String getString(Integer num) {
return num.toString();
}
public String getString(Integer num)
{
return num.toString();
}
Copy the code
1. Open and close curly braces should be in a newline style
In Golang, only one style of newline is allowed:
func getString(num int) string {
return strconv.Itoa(num)
}
Copy the code
If the following newline style occurs, an error will be reported and the compilation will not be completed:
2. The variable must be used after declaration. If not, use _ instead
In Java, a variable can be declared but not used. Golang’s variable must be used. Otherwise, you need to replace the variable name with _, indicating that the variable will not be used more than:
func getString(num int) string {
temp := num // Cannot compile without users
_ := num // Compile normally
return strconv.Itoa(num)
}
Copy the code
3. Visibility domain rules
Whereas Java controls the visibility of methods, variables, and classes by using the private, protected, and public keywords, Golang controls the visibility only in one way: when the field starts with an uppercase letter, it is visible to the outside world; when it starts with a lowercase letter, it is visible to the inside members of the package.
- entity
package entity
type Person struct {
Name string
Age int
id string
}
type student struct {
detail Person
}
func test(a) {
// This package is visible
person := &student{detail: Person{
Name: "ARong",
Age: 21,
id: "211",
}}
fmt.Println(person)
}
Copy the code
- main
package main
import (
"fmt"
entity "others/scope"
)
func main(a) {
// The id field is not visible
person := &entity.Person{
Name: "ARong",
Age: 21,
}
fmt.Println(person)
}
Copy the code
2.2. Variable declaration and initialization
In Java, the common syntax for variable declaration and initialization is:
// Object: type to declare, v: variable name, new Object() variable initialization
Object v = new Object();
Copy the code
Golang uses the var keyword to declare variables:
// var: variable definition, v1: variable name, int: variable type
var v1 int
var v2 string
var v3 [10]int / / array
var v4 []int // Array slice
var v5 struct {
f int
}
var v6 *int / / pointer
var v7 map[string]int // Map. Key is a string and value is an int
var v8 func(a int) int
var v9,v10 int // Both v9 and v10 are declared as int
Copy the code
You can also use := automatically infer the variable type:
var v1 int = 10 // The correct way to use 1
var v2 = 10 // The compiler can automatically deduce the type of v2 by using the correct method 2
v3 := 10 // The compiler can automatically deduce the type of v3 when using the correct mode 3
Copy the code
2. For basic types, declaration is initialization. For reference types, the declaration is initialized to nil
In Java, if you declare a variable inside a method but do not initialize it, you will get a compilation error when using it:
public void solve(a) {
int num;
Object object;
System.out.println(num); // Compile error
System.out.println(object); // Compile error
}
Copy the code
In Golang, for basic types, declaration is initialization; For reference types, the declaration is initialized to nil. This can greatly avoid the occurrence of NPE.
func main(a) {
var num int
var hashMap *map[string]int
fmt.Println(num) // num = 0
fmt.Println(hashMap) // &hashMap== nil
}
Copy the code
2.3. Value type and reference type
Golang’s type system is similar to That of Java, but it’s important to note that arrays in Java are reference types, whereas arrays in Golang are value types. When passing an array to a method, Java can directly modify the inner values of the array (a shallow copy). Golang, however, makes a full copy (a deep copy) :
- Java
public static void main(String[] args) {
int[] array = {1.2.3};
change(array);
System.out.println(Arrays.toString(array)); / / - 1, 2, 3
}
private static void change(int[] array) {
array[0] = -1;
}
Copy the code
- Golang
func main(a) {
array := [...]int{1.2.3}
change(array)
fmt.Println(array) / / 1, 2, 3
}
func change(array [3]int) {
array[0] = - 1
}
Copy the code
It is also worth noting that in Golang, only arrays of the same length and type are considered to be of the same type. For example, [2]int and [3]int are considered to be of different types. This causes a compilation error when passing arguments.
So arrays are rarely used directly in Golang, and slices (based on array Pointers) are used instead of arrays.
In Golang, only slice, pointer, channel, map, and func are reference types, which means that when you pass arguments, you are essentially copying their Pointers. Internal changes directly affect external ones:
func main(a) {
slice := []int{1.2.3}
changeSlice(slice)
fmt.Println(slice) / / - 1, 2, 3
mapper := map[string]int {
"num": 0,
}
changeMap(mapper)
fmt.Println(mapper) // num = -1
array := [...]int{1.2.3}
changePointer(&array)
fmt.Println(array) / / - 1, 2, 3
intChan := make(chan int.1)
intChan <- 1
changeChannel(intChan)
fmt.Println(<- intChan) // -1
}
func changeChannel(intChan chan int) {
<- intChan
intChan <- - 1
}
func changePointer(array *[3]int) {
array[0] = - 1
}
func changeMap(mapper map[string]int) {
mapper["num"] = - 1
}
func changeSlice(array []int) {
array[0] = - 1
}
Copy the code
Structs, functions and Pointers
3.1 declaration and use of structure
The most striking difference between Golang and Java is that there is no such thing as a “class” in Golang. The structures that organize data entities are called structures in Golang. Functions can exist outside of a “class,” and can be called depending on a structure or a package name.
Structures in Golang abandon the concept of polymorphism such as inheritance and implementation, and use combinations between structures to achieve the effect of reuse methods or fields.
To declare a structure, use the type + struct keyword:
type Person struct {
Name string
Age int
id string
}
Copy the code
To use a structure is also simple. There are several ways to create a structure:
personPoint := new(entity.Person) // Create a pointer to the structure using the new method
person1 := entity.Person{} // Create the default field structure with Person{}
person2 := entity.Person{ Person{Name:x,Age:x} creates the structure and initializes the specific fields
Name: "ARong",
Age: 21,
}
fmt.Println(personPoint) // &{ 0 }
fmt.Println(person1) / / {0}
fmt.Println(person2) // {ARong 21 }
Copy the code
3.2. Differences between functions and methods
Those of you who use Java should use the word “function” very rarely, because for Java, all “functions” are built around the concept of “classes,” meaning that only “classes” contain so-called “functions,” which are called “methods.”
And the word “function” comes from process-oriented languages, so the basic difference between “function” and “method” in Golang is:
Functions are not called based on a structure but on a package name, and methods are called based on a structure.
Here’s an example to see the difference between a method and a function:
- entity
package entity
import "fmt"
type Person struct {
Name string
Age int
id string
}
// Person structure/pointer to callable "methods" that belong to the Person structure
func (p *Person) Solve(a) {
fmt.Println(p)
}
// A "function" that can be called anywhere and does not belong to any structure can be called by entity.solve
func Solve(p *Person) {
fmt.Println(p)
}
Copy the code
- main
func main(a) {
personPoint := new(entity.Person) // Create a pointer to the structure using the new method
entity.Solve(personPoint) // Call the function
personPoint.Solve() // Method call
}
Copy the code
3.3. Use of Pointers
There is no explicit pointer operation in Java, and there is explicit pointer operation in Golang, but Golang’s pointer is not as complex as C’s to perform pointer operation.
Here’s an example of Java’s implicit pointer conversion and Golang’s explicit pointer conversion: Both the Java and Golang methods pass value types. In Java, if you pass a reference type (object, array, etc.), the pointer to it will be copied. In Golang, you must explicitly pass the Person pointer, or you will just pass a copy of the object.
Golang uses * to define and declare Pointers, and & to get Pointers to objects.
func main(a) {
p1 := entity.Person{
Name: "ARong1",
Age: 21,
}
changePerson(p1)
fmt.Println(p1.Name) // ARong1
changePersonByPointer(&p1)
fmt.Println(p1.Name) // ARong2
}
func changePersonByPointer(person *entity.Person) {
person.Name = "ARong2"
}
func changePerson(person entity.Person) {
person.Name = "ARong2"
}
Copy the code
Note that if other structures need to be combined within a structure, it is recommended to declare them as Pointers, otherwise updates will be lost.
Here is an implicit pointer conversion to the Golang method, which is automatically converted to a pointer call if an object is passed from a structure:
type Person struct {
Name string
Age int
}
// Person structure/pointer to callable "methods" that belong to the Person structure
func (p *Person) Solve(a) {
fmt.Println(p)
}
func main(a) {
p := entity.Person{
Name: "ARong",
Age: 21,
}
pp := &p
pp.Solve() / / explicit
p.Solve // Implicit, automatically convert p to &p
}
Copy the code