Article Directory
foreword
Record some grammatical sugar of Go, of course, some simple syntax may be skipped~
1. Structural analysis
package main
import (
"fmt"
)
func Hello(str string) {
fmt.Println("Hello " + str)
}
func main() {
Hello("World!")
}
Here is a simple Go
code where we can see
- The first line
package main
represents that this file is part of the main package,main
which is the entry package of the program. The first line of package master means that this file is part of the main package, which is also the entry package of the program. - The operation on the third line
import
represents the introduction of some standard library packages, which can be easily matched withC
language preprocessing#include
- The seventh line here is
Go
the structure of a function. We accept astring
type ofstr
variable here, and thenHello
print it out with a prefix - The eleventh line here is the main function, analogous to
C
the languagemain
, that is, the startup entry of the program
2. Variables & constants
Basic types of variables:
①: bool type
record true or false
②: Numerical type
int8
、int16
、int32
、int64
、int
uint8
、uint16
、uint32
、uint64
、uint
float32
,float64
complex64
,complex128
byte
rune
record value
We found that some variables are followed by a number, which actually indicates the size of the bits occupied by this variable. For example, it means that it
int8
occupies8
a bit, and the number of numbers that can be represented is 2 8 2^828 considered0 0In the case of 0 and negative numbers,int8
the range of this representation is:− 2 7 -2^7−27 ~ 2 7 − 1 2^7-1 27−1 Another analogy, where the prefix addedu
means unsigned type, that is, there is no negative number, directly from0
2x − 1 2^x-12x−1 is enough
③: string type
Used to record values of type string
variable definition
①: The first type is var
defined by keywords
var a = "hello"
var b = 3
var c float64 = 3.14
Note that if you do not initialize the variable here, you need to bring the type of the variable:
var a string
var b int
var c float64
②: Direct definition
a := "hello"
b := 3
c := 3.14
Of course, you can use strong conversion when defining variables
constant definition
var
The definition of a constant is actually to turn the variable into const
a keyword.
const str = "Hello World!"
3. Branch & Loop
if-else
package main
import (
"fmt"
)
func main() {
var a int
fmt.Scanf("%d", &a)
if a < 10 {
fmt.Println("step1")
} else if a < 20 {
fmt.Println("step2")
} else {
fmt.Println("step3")
}
}
Here we find that C/C++
the difference between and is that the judgment condition is not wrapped in parentheses. If you have to add parentheses, Go
it can also run
switch case
package main
import (
"fmt"
)
func main() {
var a int
fmt.Scanf("%d", &a)
switch a {
case 1:
fmt.Println("This is 1")
case 2:
fmt.Println("This is 2")
case 3:
fmt.Println("This is 3")
default:
fmt.Println("This is error")
}
}
- In
c++
it,switch case
if you don'tcase
add it under the goalbreak
, you will continue to run all the thingscase
, andgo
you don't need to add it in the languagebreak
.- Compared with
C
orC++
, the functionsgo
in the languageswitch
are more powerful. Arbitrary variable types can be used and can even be used to replace arbitraryif else
statements. You canswitch
not add any variables in the back, and thencase
write conditional branches in it.if else
In this way, the code logic will be clearer than if you use multiple codes
for loop
Go
Only one for
loop, but enough
package main
import (
"fmt"
)
func main() {
var a int
fmt.Scanf("%d", &a)
for i := 1; i < a; i++ {
fmt.Println("index = ", i)
}
}
The writing method of while type:
package main
import (
"fmt"
)
func main() {
var a int
fmt.Scanf("%d", &a)
var i int = 1
for i <= a {
fmt.Println("index = ", i)
i++
}
}
for-range
for key, value := range oldMap {
newMap[key] = value
}
key
Note that sometimes it will not be used here , so you can use _
an underscore instead, so that you will not report the error of not using this variable
4. Array
The definition of the array only needs to place the requested space between the variable name and the type
eg:
//声明数组
var a[10]int
//声明并初始化操作
var d = [3]int{
1,2,3}
A two-dimensional array is similar to:
var a[5][5]int
var d = [5][5]int{
{
1,2,3,4,5}}
The length of the array can len
be obtained by the function, for example
//声明数组
var a[10]int
//声明并初始化操作
var d = [3]int{
1,2,3}
//输出长度
fmt.Println(len(d))
Element access is just normal subscript access, for example:a[i][j]
Five, function
standard format:
func function_name( [parameter list] ) [return_types] {
函数体
}
Structure record:
// 传入两个 int 类型的值,然后返回其和,且也是int类型
func add(a int, b int) int {
return a + b
}
// 传入一个stirng参数,然后没有返回值
func printt(str string) {
fmt.Println("Hello", str)
}
Go
A function can return multiple values, generally speaking, the first is the return value of the function, and the second is the error message.
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
The case where an error is returned:
func (c *Client) Do(req *Request) (*Response, error) {
return c.do(req)
}
When we call this function, we need to give two variables to accept the return value:
resp, err := client.Do(req)
6. Slicing
The difference between slices ( slice
) and arrays is that the length of slices is not fixed but variable, which is more versatile than arrays.
The slice declaration needs to make
be carried out through , and the type and length of the slice need to be specified. For example, the following creates a length of 3 33 typesstring
of slices.
// 声明一个空切片
s1 := make([]string, 3)
// 声明并初始化
s2 :=[] int {
1,2,3,4,5,6}
capacity
In addition to the length, a slice also has a concept of capacity ( ), which can be specified at the same time when declaring a slice.
s := make([]string, 3, 10)
s1 := s[startIndex:endIndex]
You can create a new slice through it s1
, and s
it can be an array. The rest of the operations seem to be similar to the python
slice of the slice, but go
the slice of the slice is more like a variable-length array or a linked list. The go
support append
function is used to append values to the slice, and the support copy
function is used to copy the slice.
package main
import "fmt"
func main() {
var numbers []int
printSlice(numbers)
/* 允许追加空切片 */
numbers = append(numbers, 0)
printSlice(numbers)
/* 向切片添加一个元素 */
numbers = append(numbers, 1)
printSlice(numbers)
/* 同时添加多个元素 */
numbers = append(numbers, 2,3,4)
printSlice(numbers)
/* 创建切片 numbers1 是之前切片的两倍容量*/
numbers1 := make([]int, len(numbers), (cap(numbers))*2)
/* 拷贝 numbers 的内容到 numbers1 */
copy(numbers1,numbers)
printSlice(numbers1)
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}
7. Pointer
It seems that C/C++
the operation of the pointer in is the same, by *
accessing, and then &
taking the address symbol
However, Go
the pointer in does not support pointer arithmetic. For example, the following code will report an error:
main.go:6: invalid operation: p++ (non-numeric type *[3]int)
package main
func main() {
b := [...]int{
109, 110, 111}
p := &b
p++
}
new creates a pointer
Here mark the format:
ptr := new(int)
, where int
can be replaced by other data types
other
-
Regarding pointer dereferencing is
C/C++
similar to -
*
When we want to pass pointer parameters into a function, we need to use it to indicate that we accept pointers when we define the function
I feel that Go
there is a mentally handicapped grammar, first look at the code:
package main
import (
"fmt"
)
func find_max(a []int) int {
l := len(a)
ans := a[0]
for i := 0; i < l; i++ {
if a[i] > ans {
ans = a[i]
}
}
return ans
}
func main() {
var d = [3]int{
1, 2, 3}
fmt.Println(find_max(d))
}
This is also C/C++
a normal array parameter passing, but an error will be reported here:
cannot use d (variable of type [3]int) as []int value in argument to find_max
The meaning is probably a slice, and an array is a []int
passed in , so an error will be reported. We need to change the 20th 20thd
The data of row 20 is changed to slice, namely:
fmt.Println(find_max(d[:]))
8. Structure
Structure declaration syntax:
type StructName struct{
FieldName type
}
Different members can be written directly in new lines without ,
separation, as follows:
type StructName struct{
a int
b float32
c string
d bool
}
Define the structure variable:
var t1 StructName
t2 := StructName{
a: 1,
b: 1.1,
c: "hello",
d: true,
}
t3 := StructName{
1, 1.1, "hello", true}
member function
Member functions are written outside the structure, the format is as follows:
func (t StructName) func_name(str string) int {
return 1
}
Here we pass in the current structure, of course, we can also use the structure pointer, so that we can modify the current structure variable
json to structure
JSON to Golang Struct
When we process JSON data, we need to construct JSON into a nest of one or more structures, so suppose we have the following JSON data:
{
"rc": 0,
"wiki": {
"known_in_laguages": 63,
"description": {
"source": "tangible and intangible thing, except labor tied services, that satisfies human wants and provides utility",
"target": null
},
"id": "Q28877",
"item": {
"source": "good",
"target": "商品"
},
"image_url": "http://www.caiyunapp.com/imgs/link_default_img.png",
"is_subject": "true",
"sitelink": "https://www.caiyunapp.com/read_mode/?id=6354777915466339550246c5"
},
"dictionary": {
"prons": {
"en-us": "[gʊd]",
"en": "[gud]"
},
"explanations": [
"a.好的;善良的;快乐的;真正的;宽大的;有益的;老练的;幸福的;忠实的;优秀的;完整的;彻底的;丰富的",
"n.利益;好处;善良;好人",
"ad.=well"
],
"synonym": [
"excellent",
"fine",
"nice",
"splendid",
"proper"
],
"antonym": [
"bad",
"wrong",
"evil",
"harmful",
"poor"
],
"wqx_example": [
[
"to the good",
"有利,有好处"
],
[
"good, bad and indifferent",
"好的,坏的和一般的"
],
[
"good innings",
"长寿"
],
[
"good and ...",
"很,颇;完全,彻底"
],
[
"do somebody's heart good",
"对某人的心脏有益,使某人感到愉快"
],
[
"do somebody good",
"对某人有益"
],
[
"be good for",
"对…有效,适合,胜任"
],
[
"be good at",
"在…方面(学得,做得)好;善于"
],
[
"as good as one's word",
"信守诺言,值得信赖"
],
[
"as good as",
"实际上,几乎等于"
],
[
"all well and good",
"也好,还好,很不错"
],
[
"a good",
"相当,足足"
],
[
"He is good at figures . ",
"他善于计算。"
]
],
"entry": "good",
"type": "word",
"related": [],
"source": "wenquxing"
}
}
Let's write the structure by ourselves, maybe we can write it, but it's very troublesome to write it back. At this time, we need to use the above tools. JSON
Go to the structure
Convert it out:
type AutoGenerated struct {
Rc int `json:"rc"`
Wiki struct {
KnownInLaguages int `json:"known_in_laguages"`
Description struct {
Source string `json:"source"`
Target interface{
} `json:"target"`
} `json:"description"`
ID string `json:"id"`
Item struct {
Source string `json:"source"`
Target string `json:"target"`
} `json:"item"`
ImageURL string `json:"image_url"`
IsSubject string `json:"is_subject"`
Sitelink string `json:"sitelink"`
} `json:"wiki"`
Dictionary struct {
Prons struct {
EnUs string `json:"en-us"`
En string `json:"en"`
} `json:"prons"`
Explanations []string `json:"explanations"`
Synonym []string `json:"synonym"`
Antonym []string `json:"antonym"`
WqxExample [][]string `json:"wqx_example"`
Entry string `json:"entry"`
Type string `json:"type"`
Related []interface{
} `json:"related"`
Source string `json:"source"`
} `json:"dictionary"`
}
Nine, error handling
Go
The language provides a very simple error handling mechanism through the built-in error interface.
error
Type is an interface type, here is its definition:
type error interface {
Error() string
}
If an exception is thrown inside the function, then there should be one more errors
receiving variable for the current function, such as the following code example:
type user struct {
name string
password string
}
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
return nil, errors.New("not found")
}
When we need to call this function, we need to call it like this:
us,err = findUser([]user{
{
"xie","1234abcd"}},"xie")
10. Standard Library
Go has a very rich built-in standard library tools. Commonly used standard libraries include string manipulation, string formatting, json processing, time processing, etc.
string manipulation
a := "hello"
// 是否包含
fmt.Println(strings.Contains(a, "ll")) // true
// 字符统计
fmt.Println(strings.Count(a, "l")) // 2
// 判断字符串开头
fmt.Println(strings.HasPrefix(a, "he")) // true
// 判断字符串结尾
fmt.Println(strings.HasSuffix(a, "llo")) // true
// 查找字符串
fmt.Println(strings.Index(a, "ll")) // 2
// 字符串拼接
fmt.Println(strings.Join([]string{
"he", "llo"}, "-")) // he-llo
// 复制字符串指定次数
fmt.Println(strings.Repeat(a, 2)) // hellohello
// 字符串替换
fmt.Println(strings.Replace(a, "e", "E", -1)) // hEllo
// 字符串分割
fmt.Println(strings.Split("a-b-c", "-")) // [a b c]
// 转为小写
fmt.Println(strings.ToLower(a)) // hello
// 转为大写
fmt.Println(strings.ToUpper(a)) // HELLO
// 字符串长度
fmt.Println(len(a)) // 5
string formatting
Println
The most commonly used function is to print and wrap, and Printf
the string can be printed in the specified format.
+v
Field and value details can be printed.
#v
The structure and details of the entire structure can be printed out.
s := "hello"
n := 123
p := point{
1, 2}
fmt.Println(s, n) // hello 123
fmt.Println(p) // {1 2}
fmt.Printf("s=%v\n", s) // s=hello
fmt.Printf("n=%v\n", n) // n=123
fmt.Printf("p=%v\n", p) // p={1 2}
fmt.Printf("p=%+v\n", p) // p={x:1 y:2}
fmt.Printf("p=%#v\n", p) // p=main.point{x:1, y:2}
f := 3.141592653
fmt.Println(f) // 3.141592653
fmt.Printf("%.2f\n", f) // 3.14
json processing
Go
It is very simple to process json
, you only need to change the first letter of the field in the structure to uppercase to use the built-in JSON
tools for processing.
Go
Some special types in , such as Channel
, complex
, function
cannot be parsed into JSON
.
Go
The object in JSON
is only supported string
as an object key
. For map
, it must be of map[string]T
this type, T
which can be Go
any type in the language.
Go
The json
processing is done by the method Marshal
.Unmarshal
Marshal
The method used for custom encoding json
, that is, to convert variables and objects into json
, after the conversion, you need to use string
the method to force the conversion, otherwise it will print out 16 16Hexadecimal string.
Unmarshal
Used to customize the decoding json
method, that is, it will json
be converted to an object.
type userInfo struct {
Name string
Age int `json:"age"` // 自定义json输出的字段
Hobby []string
}
func main() {
a := userInfo{
Name: "wang", Age: 18, Hobby: []string{
"Golang", "TypeScript"}}
buf, err := json.Marshal(a)
if err != nil {
panic(err)
}
fmt.Println(buf) // [123 34 78 97...]
fmt.Println(string(buf)) // {"Name":"wang","age":18,"Hobby":["Golang","TypeScript"]}
buf, err = json.MarshalIndent(a, "", "\t")
if err != nil {
panic(err)
}
fmt.Println(string(buf))
var b userInfo
err = json.Unmarshal(buf, &b)
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", b)
// main.userInfo{Name:"wang", Age:18, Hobby:[]string{"Golang", "TypeScript"}}
time processing
Go
Provides many commonly used time processing functions, such as Now
parsing strings, converting strings, obtaining timestamps, etc. When manipulating time-related methods, you need to import time
the package.
// 获取当前时间
now := time.Now()
fmt.Println(now) // 2022-03-27 18:04:59.433297 +0800 CST m=+0.000087933
t := time.Date(2022, 3, 27, 1, 25, 36, 0, time.UTC)
t2 := time.Date(2022, 3, 27, 2, 30, 36, 0, time.UTC)
fmt.Println(t) // 2022-03-27 01:25:36 +0000 UTC
// 获取时间的年月日
fmt.Println(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()) // 2022 March 27 1 25
// 时间转字符串
fmt.Println(t.Format("2006-01-02 15:04:05")) // 2022-03-27 01:25:36
// 获取时间差
diff := t2.Sub(t)
fmt.Println(diff) // 1h5m0s
fmt.Println(diff.Minutes(), diff.Seconds()) // 65 3900
// 解析字符串
t3, err := time.Parse("2006-01-02 15:04:05", "2022-03-27 01:25:36")
if err != nil {
panic(err)
}
fmt.Println(t3 == t) // true
// 获取时间戳
fmt.Println(now.Unix()) // 1648738080
11. Data structure
Go
The language has a built-in data structure, namelymap
Map
It is an unordered collection of key ( key
) value ( value
) pairs, also known as mapping and dictionary.
Map
is unordered and supports operations like arrays and slices.
Map
The statement is as follows:
m := make(map[string]int)
Among them, string
it is the key, int
and it is the value. The access to the element is also accessed according to the subscript. For the key-value pair that does not exist, it is returned. There 0
is also a problem here. Assuming that a key-value pair is key
also the same 0
, sometimes there may be misunderstandings. Therefore, Go
in the query result of the key-value pair, two values are returned, one is the result, and the other is whether it exists, as follows:
r, ok := m["unknow"]
fmt.Println(r, ok) // 0 false
To delete a key-value pair, you can use delete
the function
delete(m, "one")
Another big guy Go
realized it withSTL
GoSTL
is ago
library of language data structures and algorithms, similarC++
butSTL
more powerful. Combined withgo
the characteristics of the language, most data structures have implemented coroutine security, and you can specify whether to enable it through configuration parameters when creating objects.
gostl:https://github.com/liyue201/gostl