The basic grammar of 2 Go

1. Basic types

  • bool
  • string
  • int、int8、int16、int32、int64
  • uint、uint8、uint16、uint32、uint64、uintptr
  • byte // alias for uint8
  • rune // Alias ​​of int32 represents a Unicode code
  • float32、float64
  • complex64、complex128

2. Three declaration variables

2.1 Standard format

var name type

Among them, var is the keyword for declaring the variable, name is the name of the variable, and type is the type of the variable

2.2 Batch format

var (
    a int
    b string
    c []float32
    d func() bool
    e struct {
    
    
        x int
    }
) 

2.3 Short form

name:= expression
i, j := 0, 1
Note that short variable declarations have the following restrictions:
define variables and explicitly initialize them at the same time. //Equivalent to assignment, you don't need to declare the type of the obtained variable anymore.
Data type cannot be provided. // Because the assignment will directly have a type, so there is no need to provide a data type,
it can only be used inside the function. //Global definitions still have to use var

Example:

func main() {
    
    
   x:=100
   a,s:=1, "abc"
}

3. Variable initialization

3.1 Standard format

var 变量名 类型 = 表达式
var hp int = 100

In the above code, 100 and int are both of int type, and int can be considered as redundant information, so the writing method of initialization can be further simplified

3.2 Format of compiler-derived types

var defence = 
var damageRate float32 = 0.17
var damage = float32(attack-defence) * damageRate
fmt.Println(damage)

Code description:

  • In lines 1 and 2, the rvalue is an integer, and the attack and defense variables are of type int.
  • On line 3, 0.17 is used in the rvalue of the expression. Since the Go language is like the C language, the compiler will try to increase the precision to avoid the loss of precision in the calculation. So if you don't specify the type of the damageRate variable here, the Go language compiler will deduce the damageRate type as float64. We don't need the precision of float64 here, so we need to force the type to be specified as float32.
  • In line 4, the numerical result after subtracting attack and defense is still an integer, use float32() to convert the result to float32 type, and multiply it with the damageRate of float32 type, the damage type is also float32 type

3.3 Short variable declaration and initialization

如果 hp 已经被声明过,但依然使用:=时编译器会报错
// 声明 hp 变量
var hp int
// 再次声明并赋值
hp := 10

Example:

conn, err := net.Dial("tcp", "127.0.0.1:8080") net.Dial
provides to initiate a network connection according to the specified protocol and address, this function has two return values, one is the connection object (conn), One is the error object (err)

4. Simultaneous assignment of multiple variables

var b = 200
b, a = a, b
fmt.Println(a, b)

5. Variable scope

5.1 Local variables

import (
    "fmt"
)
func main() {
    
    
    //声明局部变量 a 和 b 并赋值
    var a int = 3
    var b int = 4
    //声明局部变量 c 并计算 a 和 b 的和
    c := a + b
    fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c)
}

5.2 Global variables

import "fmt"
//声明全局变量
var c int
func main() {
    
    
    //声明局部变量
    var a, b int
    //初始化参数
    a = 3
    b = 4
    c = a + b
    fmt.Printf("a = %d, b = %d, c = %d\n", a, b, c)
}

5.3 Formal parameters

import (
    "fmt"
)
//全局变量 a
var a int = 13
func main() {
    
    
    //局部变量 a 和 b
    var a int = 3
    var b int = 4
    fmt.Printf("main() 函数中 a = %d\n", a)
    fmt.Printf("main() 函数中 b = %d\n", b)
    c := sum(a, b)
    fmt.Printf("main() 函数中 c = %d\n", c)
}
func sum(a, b int) int {
    
    
    fmt.Printf("sum() 函数中 a = %d\n", a)
    fmt.Printf("sum() 函数中 b = %d\n", b)
    num := a + b
    return num
}

6. Formatted output

import (
    "fmt"
    "math"
)
func main() {
    
    
    fmt.Printf("%f\n", math.Pi)
    fmt.Printf("%.2f\n", math.Pi)
}

Generic placeholders:

  • %v is used by default and can be used universally
  • %T output type
  • %% output percent sign

Boolean:

  • %t

The width identifier is shown in the figure below:

n := 12.34
fmt.Printf("%f\n", n)
fmt.Printf("%9f\n", n)
fmt.Printf("%.2f\n", n)
fmt.Printf("%9.2f\n", n)
fmt.Printf("%9.f\n", n)

输出:
12.340000
12.340000
12.34
    12.34
       12

7. Combination of integer, floating point and Boolean values

package main
import "fmt"
func main() {
    
    
   i := 0
   var c float32 = 0.2
   b := float32(sum(3, 4))
   if b > 7 {
    
    
      i = 1
   }
   fmt.Printf("当前c的值为:%.2f\n", c)
   fmt.Printf("当前i的值为:%d\n", i)
   b2 := isBool(2)
   fmt.Printf("b2的值为: %t\n", b2)
}
func sum(a, b int) int {
    
    
   return a + b
}
func isBool(i int) bool {
    
     return i != 0 }

8. String

8.1 Common symbols

\n: newline
\r: carriage return
\t: tab key
\u or \U: Unicode character
\: backslash itself

8.2 Defining multiline strings

Use the ` symbol to define
the internal string to be output as original text, and the escape symbol is invalid

package main
import "fmt"
func main() {
    
    
   const str1 = `第一行
第二行
第三行
\r\n
`
   fmt.Printf("str1:%v", str1)
}

8.3 String methods

8.3.1 String Length

  1. Calculated in bytes
package main
import "fmt"
func main() {
    
    
   tip1 := "gen ji is a ninja"
   fmt.Println(len(tip1))
   tip2 := "忍者"
   fmt.Println(len(tip2))
}

输出:
17  // 纯英文与空格只占用一个长度
6  //一个汉字占用三个长度
  1. Calculate according to the number of characters (to calculate the number of characters in UTF8, you need to use the RuneCountInString() function)
package main
import (
   "fmt"
   "unicode/utf8"
)
func main() {
    
    
   fmt.Println(utf8.RuneCountInString("龙龟冲!"))
   fmt.Println(utf8.RuneCountInString("龙龟, Fight!"))
}

8.4 Get string elements

ASCii code output

theme := "狙击 start"
for i := 0; i < len(theme); i++ {
    
    
    fmt.Printf("ascii: %c  %d\n", theme[i], theme[i])
}

Unicode encoded output

package main
import "fmt"
func main() {
    
    
   theme := "狙击 start"
   for i, s := range theme {
    
    
      fmt.Printf("%d Ascii: %c %d\n", i, s, s)
   }
}

输出:
0 Ascii:29401
3 Ascii:20987
6 Ascii:   32
7 Ascii: s 115
8 Ascii: t 116
9 Ascii: a 97
10 Ascii: r 114
11 Ascii: t 116

8.5 String value acquisition

tracer := "死神来了, 死神bye bye"
comma := strings.Index(tracer, ", ")
pos := strings.Index(tracer[comma:], "死神")  //等价于从", 死神bye bye"字符串开始查找
fmt.Println(comma, pos, tracer[comma+pos:])

输出:
12 3 死神bye bye

8.6 String concatenation

package main
import (
   "bytes"
   "fmt"
)
func main() {
    
    
   a := "今天"
   b := "不错"
   var stringBuffer bytes.Buffer
   stringBuffer.WriteString(a)
   stringBuffer.WriteString(b) //这种拼接方式比+号高效
   fmt.Println(stringBuffer.String())
}

9. Type conversion

Loss of precision problem

package main
import (
   "fmt"
   "math"
)
func main() {
    
    
   // 输出各数值范围
   fmt.Println("int8 range:", math.MinInt8, math.MaxInt8)
   fmt.Println("int16 range:", math.MinInt16, math.MaxInt16)
   fmt.Println("int32 range:", math.MinInt32, math.MaxInt32)
   fmt.Println("int64 range:", math.MinInt64, math.MaxInt64)
   // 初始化一个32位整型值
   var a int32 = 1047483647
   // 输出变量的十六进制形式和十进制值
   fmt.Printf("int32: 0x%x %d\n", a, a)
   // 将a变量数值转换为十六进制, 发生数值截断
   b := int16(a)
   // 输出变量的十六进制形式和十进制值
   fmt.Printf("int16: 0x%x %d\n", b, b)
   // 将常量保存为float32类型
   var c float32 = math.Pi
   // 转换为int类型, 浮点发生精度丢失
   fmt.Println(int(c))
}

10. pointer

10.1 Pointer value

After using the & operator to fetch the address of an ordinary variable and get the pointer of the variable, you can use the * operator on the pointer, that is, the value of the pointer, the code is as follows

package main
import (
    "fmt"
)
func main() {
    
    
    // 准备一个字符串类型
    var house = "Malibu Point 10880, 90265"
    // 对字符串取地址, ptr类型为*string
    ptr := &house
    // 打印ptr的类型
    fmt.Printf("ptr type: %T\n", ptr)
    // 打印ptr的指针地址
    fmt.Printf("address: %p\n", ptr)
    // 对指针进行取值操作
    value := *ptr
    // 取值后的类型
    fmt.Printf("value type: %T\n", value)
    // 指针取值后就是指向变量的值
    fmt.Printf("value: %s\n", value)
}

The address operator & and the value operator * are a pair of complementary operators, & takes the address, and * takes the value pointed to by the address according to the address

package main
import "fmt"
func swap(a, b *int) {
    
    
   fmt.Println(a)
   fmt.Println(b)
   *b, *a = *a, *b
}
func main() {
    
    
   x, y := 1, 2
   swap(&x, &y)
   fmt.Println(x, y)
}

输出:
21
package main
import "fmt"
func swap(a, b *int) {
    
    
    b, a = a, b
}
func main() {
    
    
    x, y := 1, 2
    swap(&x, &y)
    fmt.Println(x, y)
}

输出12

10.2 Receive startup parameters

The built-in flag package of the Go language implements the parsing of command line parameters. The flag package makes it easier to develop command line tools. The
following code defines some command line commands and corresponding variables in advance, and enters the corresponding parameters at runtime. The command line data can be obtained after the flag package is parsed

package main
// 导入系统包
import (
   "flag"
   "fmt"
)
// 定义命令行参数
var mode = flag.String("mode", "", "process mode")
func main() {
    
    
   // 解析命令行参数
   fmt.Printf("%T\n", mode)
   flag.Parse()
   // 输出命令行参数
   fmt.Println(*mode)
}

Name this code main.go, and then use the following command line to run: go run main.go --mode=fast The output of the command line is as follows:
fast

The code description is as follows:
flag defines variables of pointer type
. Line 10 defines a mode variable through flag.String. The type of this variable is *string. The next three parameters are as follows:
Parameter name: use this name when inputting parameters on the command line.
The default value of the parameter value: corresponds to the variable type created by the function used by the flag, String corresponds to a string, Int corresponds to an integer, Bool corresponds to a Boolean, etc.
Parameter description: When using -help, it will appear in the description.
Line 15 parses the command line parameters and writes the result to the variable mode.
Line 18, print the variable pointed to by the mode pointer.

insert image description here

10.3 Creating pointer methods

new(类型)

package main
import "fmt"
func main() {
    
    
   a := new(string)
   fmt.Printf("%T\n", a)  //创建了一个指针类型
   *a = "今天天气不错"
   fmt.Println(*a)
}

输出:
*string
今天天气不错

11. Go Variable Lifecycle

11.1 Types of variables

Global variable: its life cycle is consistent with the running cycle of the entire program;
local variable: its life cycle is dynamic, starting from the declaration statement that creates the variable until the variable is no longer referenced; formal parameters
and Function return value: They are all local variables, created when the function is called, and destroyed after the function call ends.

Heap: The heap is used to store memory segments that are dynamically allocated during process execution. Its size is not fixed and can be expanded or reduced dynamically. When a process calls functions such as malloc to allocate memory, the newly allocated memory is dynamically added to the heap (the heap is expanded). When using functions such as free to free memory, the freed memory is removed from the heap (the heap is reduced);

Stack (stack): The stack, also known as the stack, is used to store the local variables temporarily created by the program, that is, the local variables defined in the braces { } of our function.

11.2 Variable Escaping

var global *int
func f() {
    
    
    var x int
    x = 1
    global = &x
}
func g() {
    
    
    y := new(int)
    *y = 1
}
  • In the above code, the variable x in the function f must be allocated on the heap, because it can still be found through the package-level global variable after the function exits
    , although it is defined inside the function. In Go language terms, this local variable x escapes from the function f.
  • On the contrary, when the function g returns, the variable *y is no longer used, which means it can be recycled immediately.
    Therefore, *y does not escape from the function g, the compiler can choose to allocate the storage space of *y on the stack , or it can choose to allocate it on the heap, and then the GC (garbage collection mechanism) of Go language reclaims the memory of this variable space.
  • In short, although the x variable in the f function is defined locally, but because its value is received by another variable in the form of a pointer, its pointer address can actually be used in the external global, so In Go terminology this phenomenon is called escape
  • However, in the g function, there is no external variable to receive the pointer address of y, so when the function ends, the memory space of the variable can be reclaimed by GC
  • In actual development, it is not necessary to deliberately implement variable escaping behavior, because escaping variables require additional allocation of memory, and performance optimization may have a slight impact

12. Constants

Constants in the Go language are
defined using the keyword const, which is used to store data that will not change. Constants are created at compile time, even if they are defined inside functions, and can only be Boolean and numeric (integer, floats and complex numbers) and strings. Due to compile-time restrictions, expressions defining constants must be constant expressions that can be evaluated by the compiler

In Go, you can omit the type specifier [type] because the compiler can infer the type of the variable from its value.

  • Explicit type definition: const b string = "abc"
  • Implicit type definition: const b = "abc"

The value of a constant must be determinable at compile time, and the calculation process can be involved in its assignment expression, but all values ​​used for calculation must be available during compilation.

  • Correct way: const c1 = 2/3
  • Bad practice: const c2 = getNumber() // raises build error: getNumber() used as value

If it is a batch-declared constant, the initialization expressions on the right of the other constants except the first one can be omitted. If the initialization expression is omitted, it means that the initialization expression of the previous constant is used, and the corresponding constant type is also the same. For example:

const (
    a = 1
    b
    c = 2
    d
)
fmt.Println(a, b, c, d) // "1 1 2 2"

constant generator

Constant declarations can be initialized using the iota constant generator, which is used to generate a set of constants initialized with similar rules

package main
import "fmt"
func main() {
    
    
   type Weekday int
   const (
      Sunday Weekday = iota
      Monday
      Tuesday
      Wednesday
      Thursday
      Friday
      Saturday
   )
   fmt.Println(Sunday)
   fmt.Println(Monday)
   fmt.Println(Tuesday)
   fmt.Println(Wednesday)
   fmt.Println(Thursday)
   fmt.Println(Friday)
   fmt.Println(Saturday)
}

输出:
0
1
2
3
4
5
6

13. Keywords and Identifiers

The lexical elements of the Go language include five
types, namely identifiers, keywords, operators, delimiters, and literals, which are the components that make up Go language codes and programs. The most basic unit.

13.1 Keywords

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

PS:坑爹的表格真难用,该优化了啊!

13.2 Identifiers

Identifier refers to the character sequence used by Go language to name various variables, methods, functions, etc. The identifier is composed of several letters, underscores _, and numbers, and the first character must be a letter

The naming of identifiers needs to comply with the following rules:

  • It consists of 26 English letters, 0~9, _;
  • cannot start with a number, for example var 1num int is wrong;
  • The Go language is strictly case-sensitive;
  • Identifiers cannot contain spaces;
  • System reserved keywords cannot be used as identifiers, such as break, if, etc.

There are a few more things to keep in mind when naming identifiers:

  • The naming of identifiers should be as short and meaningful as possible;
  • It cannot be the same as the package name in the standard library;
  • Use camel case when naming variables, functions, and constants, such as stuName, getVal;

There are also some special identifiers in the Go language, called predefined identifiers, as shown in the following table:
insert image description here

There are a total of 36 predefined identifiers, mainly including basic data types and built-in functions in the Go language. These predefined identifiers cannot be used as identifiers.

14 Operator precedence

List of Go language operator precedence and associativity **
insert image description here

15. Conversion of Go's string and numeric types**

package main
import (
   "fmt"
   "strconv"
)
func main() {
    
    
   value1, err1 := strconv.Atoi("哈哈") // Ascii To Int
   fmt.Println(value1)
   fmt.Println(err1)
   var x = 4
   value2 := strconv.Itoa(x) // 数字转字符串是不会出err
   fmt.Println(value2)

}

Guess you like

Origin blog.csdn.net/Python_BT/article/details/129432004