Go grammar knowledge notes

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 Gocode where we can see

  • The first line package mainrepresents that this file is part of the main package, mainwhich 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 importrepresents the introduction of some standard library packages, which can be easily matched with Clanguage preprocessing#include
  • The seventh line here is Gothe structure of a function. We accept a stringtype of strvariable here, and then Hello print it out with a prefix
  • The eleventh line here is the main function, analogous to Cthe language main, that is, the startup entry of the program

2. Variables & constants

Basic types of variables:

①: bool type
record true or false

②: Numerical type

  • int8int16int32int64int
  • uint8uint16uint32uint64uint
  • 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 int8occupies 8a bit, and the number of numbers that can be represented is 2 8 2^828 considered0 0In the case of 0 and negative numbers,int8the range of this representation is:− 2 7 -2^727 ~ 2 7 − 1 2^7-1 271 Another analogy, where the prefix addedumeans unsigned type, that is, there is no negative number, directly from02x − 1 2^x-12x1 is enough

③: string type

Used to record values ​​of type string

variable definition

①: The first type is vardefined 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

varThe definition of a constant is actually to turn the variable into consta 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, Goit 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 caseif you don't caseadd it under the goal break, you will continue to run all the things case, and goyou don't need to add it in the language break.
  • Compared with Cor C++, the functions goin the language switchare more powerful. Arbitrary variable types can be used and can even be used to replace arbitrary if elsestatements. You can switchnot add any variables in the back, and then casewrite conditional branches in it. if elseIn this way, the code logic will be clearer than if you use multiple codes

for loop

GoOnly one forloop, 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
}

keyNote 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 lenbe 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)
}

GoA 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 makebe 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 typesstringof slices.

// 声明一个空切片
s1 := make([]string, 3)
// 声明并初始化
s2 :=[] int {
    
    1,2,3,4,5,6} 

capacityIn 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 sit can be an array. The rest of the operations seem to be similar to the pythonslice of the slice, but gothe slice of the slice is more like a variable-length array or a linked list. The gosupport appendfunction is used to append values ​​to the slice, and the support copyfunction 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, Gothe 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 intcan 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 Gothere 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 []intpassed in , so an error will be reported. We need to change the 20th 20thdThe 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

https://oktools.net/json2go

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. JSONGo 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

GoThe language provides a very simple error handling mechanism through the built-in error interface.

errorType 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 errorsreceiving 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

PrintlnThe most commonly used function is to print and wrap, and Printfthe string can be printed in the specified format.

+vField and value details can be printed.

#vThe 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

GoIt 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 JSONtools for processing.

GoSome special types in , such as Channel, complex, functioncannot be parsed into JSON.

GoThe object in JSONis only supported stringas an object key. For map, it must be of map[string]Tthis type, T which can be Goany type in the language.

GoThe jsonprocessing is done by the method Marshal.Unmarshal

MarshalThe method used for custom encoding json, that is, to convert variables and objects into json, after the conversion, you need to use stringthe method to force the conversion, otherwise it will print out 16 16Hexadecimal string.

UnmarshalUsed to customize the decoding jsonmethod, that is, it will jsonbe 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

GoProvides many commonly used time processing functions, such as Nowparsing strings, converting strings, obtaining timestamps, etc. When manipulating time-related methods, you need to import timethe 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

GoThe language has a built-in data structure, namelymap

MapIt is an unordered collection of key ( key) value ( value) pairs, also known as mapping and dictionary.

Mapis unordered and supports operations like arrays and slices.

MapThe statement is as follows:

m := make(map[string]int)

Among them, stringit is the key, intand 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 0is also a problem here. Assuming that a key-value pair is keyalso the same 0, sometimes there may be misunderstandings. Therefore, Goin 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 deletethe function

delete(m, "one")

Another big guy Gorealized it withSTL

GoSTLis a golibrary of language data structures and algorithms, similar C++but STLmore powerful. Combined with gothe 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

reference blog

Guess you like

Origin blog.csdn.net/m0_46201544/article/details/128727128