1. Variables and constants

Identifiers and keywords in Golang

identifier

In Go, identifiers consist of alphanumeric characters and underscores (_) and can only start with a letter or underscore. A few examples: ABC, _, _123, a123.

The keyword

Neither keyword nor reserved word is recommended for variable names:

There are 25 keywords in Go:

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

In addition, there are 37 reserved words in Go.

    Constants:    true  false  iota  nil

        Types:    int  int8  int16  int32  int64  
                  uint  uint8  uint16  uint32  uint64  uintptr
                  float32  float64  complex128  complex64
                  bool  byte  rune  string  error

    Functions:   make  len  cap  new  append  copy  close  delete
                 complex  real  imag
                 panic  recover
Copy the code

Variables in Golang

Every variable in Go has its own type, and variables must be declared before they can be used. Duplicate declarations are not supported in the same scope. And Go language variables must be used after declaration.

Standard statement

The format of variable declaration in Go language is :(hump nomenclature is recommended for variable declaration in Golang)

varVariable name Variable typeCopy the code

Variable declarations start with the keyword var, place the variable type after the variable, and do not require a semicolon at the end of the line. Here’s an example:

var name string
var age int
var flag bool
Copy the code

Batch statements

It is cumbersome to write the var keyword for each variable declaration. Go also supports batch variable declarations:

var (
    name string
    age int
    flag bool
    money float32
)
Copy the code

Initialization of a variable

When declaring a variable, Go automatically initializes the memory region corresponding to the variable. Each variable is initialized to a default value of its type, such as 0 for integer and floating point variables. The default value of a string variable is an empty string. Boolean variables default to false. Defaults to nil for slices, functions, and pointer variables.

We can also specify an initial value for a variable when we declare it. The standard format for variable initialization is as follows:

varVariable name type = expressionCopy the code

Here’s an example:

var name string = "csp"
var age int = 22
Copy the code

Or initialize multiple variables at once

var name, age = "csp".22
Copy the code

Type inference (automatically determining the type of a variable based on its value)

Sometimes we omit the type of the variable, and the compiler initializes the variable from the value to the right of the equals sign.

var name = "csp" // automatically identifies as string
var age = 18 // automatically recognize as int
Copy the code

Short variable declaration

Inside a function, variables can be declared and initialized using the simpler := method.

package main

import "fmt"

// global variable m
var m = 100

func main(a) {
	n := 10
	m := 200 // declare the local variable m here
	fmt.Println(m, n)
}
Copy the code

Anonymous variable

When using multiple assignments, you can use anonymous variables if you want to ignore a value. Anonymous variables are represented by an underscore _, for example:

func foo(a) (int.string) {
	return 10."csp"
}
func main(a) {
	x, _ := foo() // Only the first return value from foo is accepted
	_, y := foo() // Only the second return value from foo is accepted
	fmt.Println("x=", x)
	fmt.Println("y=", y)
}
Copy the code

Anonymous variables take up no namespace and no memory is allocated, so there are no duplicate declarations between anonymous variables. (In programming languages like Lua, anonymous variables are also called dumb variables.)

Matters needing attention:

  1. Every statement outside a function must start with a keyword (var, const, func, etc.)
  2. : =Cannot be used outside a function.
  3. _Usually used as a placeholder to indicate that a value is ignored.

Constants in Golang

Constants are constant values, as opposed to variables, and are used to define values that do not change during program execution. Constants are declared in much the same way as variable declarations, except that var is replaced by const, and constants must be assigned when defined.

const pi = 3.1415
const e = 2.7182
Copy the code

Once PI and e are declared, their values cannot change for the duration of the program.

Multiple constants can also be declared together:

const (
    pi = 3.1415
    e = 2.7182
)
Copy the code

Const declares multiple constants at the same time, if the value is omitted, it is the same as the value in the previous line. Such as:

const (
    n1 = 100
    n2
    n3
)
Copy the code

In the example above, the constants n1, n2, and n3 all have values of 100.

Iota constant counters in Golang

Iota is a constant counter for the GO language and can only be used in constant expressions.

Iota is reset to 0 when the const keyword is present. Iota counts are accumulated for each new line of constant declaration in const. Using IOTA simplifies definitions and is useful when defining enums.

Here’s an example:

const (
		n1 = iota / / 0
		n2        / / 1
		n3        / / 2
		n4        / / 3
	)
Copy the code

Several common EXAMPLES of IOTA

Skip some values with _

const (
		n1 = iota / / 0
		n2        / / 1
		_
		n4        / / 3
	)
Copy the code

Iota claims to cut in line

const (
		n1 = iota / / 0
		n2 = 100  / / 100
		n3 = iota / / 2
		n4        / / 3
	)
	const n5 = iota / / 0
Copy the code

Define the order of magnitude (where << represents a left-shift operation, and 1<<10 represents a 10-bit shift to the left of the binary representation of 1, from 1 to 10000000000, or 1024 decimal. Similarly, 2<<2 shifts the binary representation of 2 two bits to the left, from 10 to 1000, which is the decimal 8.)

const(_ =iota
		KB = 1< < (10 * iota)// 1 moves 10 bits to the left == 2^10 == 1024B = 1KB
		MB = 1< < (10 * iota)// Move 10 bits to the left, 2^20 == 1MB
		GB = 1< < (10 * iota)
		TB = 1< < (10 * iota)
		PB = 1< < (10 * iota))Copy the code

Multiple IOtas are defined on a single line

const (
		a, b = iota + 1.iota + 2 / / 1, 2
		c, d                      / / 2, 3
		e, f                      / / 3, 4
	)
Copy the code

2. Basic data types

An integer in Golang

Integers fall into two broad categories:

The value can be int8, INT16, int32, and int64 by length

Corresponding unsigned integer: uint8, uint16, uint32, uint64

Among them, Uint8 is known as byte type, int16 corresponds to short type in C language, and Int64 corresponds to long type in C language.

type describe
uint8 Unsigned 8-bit integer (0 to 255)
uint16 Unsigned 16-bit integer (0 to 65535)
uint32 Unsigned 32-bit integer (0 to 4294967295)
uint64 Unsigned 64-bit integer (0 to 18446744073709551615)
int8 Signed 8-bit integers (-128 to 127)
int16 Signed 16-bit integers (-32768 to 32767)
int32 Signed 32-bit integers (-2147483648 to 2147483647)
int64 Signed 64-bit integers (-9223372036854775808 to 9223372036854775807)

Special integer

type describe
uint On 32-bit operating systemsuint32On 64-bit operating systemsuint64
int On 32-bit operating systemsint32On 64-bit operating systemsint64
uintptr An unsigned integer used to hold a pointer

Note: When using int and uint, do not assume that it is a 32-bit or 64-bit integer, but rather consider how int and uint might differ on different platforms.

The built-in len() function that gets the length of an object returns a length that can vary depending on the platform’s byte length. In practice, the number of elements in a slice or map can be represented by an int. Ints and uints are not used when describing the structure of binary transfers, reading and writing files, in order to keep the structure of files unaffected by the length of bytes on different compilation platforms.

The representation of numbers in base

After version 1.13, the number literal syntax was introduced to make it easier for developers to define numbers in binary, octal, or hexadecimal floating-point formats, such as:

V := 0b00101101, which represents 101101 in binary and 45 in decimal. V := 0o377, which represents 377 in octal and 255 in decimal. V := 0x1p-2, which is the hexadecimal 1 divided by 2², which is 0.25.

It also allows us to separate numbers with _, for example: v := 123_456 indicates that v is equal to 123456.

We can use the FMT function to display an integer in different base forms.

package main
 
import "fmt"
 
func main(a){
	/ / decimal
	var a int = 10
	fmt.Printf("%d \n", a)  / / 10
	fmt.Printf("%b \n", a)  // the 1010 placeholder %b represents binary
 
	// octal starts with 0
	var b int = 077
	fmt.Printf("%o \n", b)  / / 77
 
	// Hexadecimal starts with 0x
	var c int = 0xff
	fmt.Printf("%x \n", c)  // ff
	fmt.Printf("%X \n", c)  // FF
}
Copy the code

Floating point in Golang

The Go language supports two floating-point numbers: float32 and float64(the default). These two floating-point data formats follow the IEEE 754 standard: floating-point numbers in float32 have a maximum range of about 3.4e38 and can be defined using constants: math.maxFloat32. The maximum range of floating-point numbers in float64 is about 1.8e308 and can be defined using a constant: math.maxFloat64.

When printing floating point numbers, you can use the FMT package with the verb %f as follows:

package main
import (
        "fmt"
        "math"
)
func main(a) {
        fmt.Printf("%f\n", math.Pi)
        fmt.Printf("%.2f\n", math.Pi)
}
Copy the code

The plural of Golang

Complex64 and complex128

var c1 complex64
c1 = 1 + 2i
var c2 complex128
c2 = 2 + 3i
fmt.Println(c1)
fmt.Println(c2)
Copy the code

Complex numbers have real and imaginary parts, and complex64 has 32-bit real and imaginary parts, and complex128 has 64-bit real and imaginary parts.

Boolean value in Golang

In Go, Boolean data is declared as bool. Boolean data has only true (true) and false (false).

Note:

  1. Boolean type variableThe default valueforfalse.
  2. Casting integers to Booleans is not allowed in Go.
  3. Booleans cannot participate in numeric operations and cannot be converted to other types.

String in Golang

Strings in the Go language appear as native data types and are used just like any other native data type (int, bool, FLOAT32, float64, etc.). The internal implementation of strings in Go uses UTF-8 encoding. String values are in double quotation marks (“). You can add non-ASCII characters directly to the Go source code, for example:

s1 := "hello"
s2 := "Hello"
Copy the code

String escape character

Common escape characters in the Go language include carriage return, line feed, single and double quotation marks, and tabs, as shown in the following table.

Escape character meaning
\r Carriage return (returns the beginning of the line)
\n Line break (jumps directly to the same column on the next line)
\t tabs
\ ' Single quotes
\" Double quotation marks
\ \ The backslash

For example, we want to print a file path for a Windows platform:

package main
import (
    "fmt"
)
func main(a) {
    fmt.Println("str := \"c:\\Code\\hello_golang\\go.exe\"")}Copy the code

Multiline string

To define a multi-line string in Go, we must use the backquotation character:

s1 := 'First line, second line, third line
fmt.Println(s1)
Copy the code

A newline between backquotes is treated as a newline in the string, but all escape characters are invalid, and the text is printed as is.

Common operations on strings

methods introduce
len(str) Finding the length of a string
+ or FMT. Sprintf Concatenated string
strings.Split segmentation
strings.contains Determine whether it contains
strings.HasPrefix,strings.HasSuffix Prefix/suffix judgment
strings.Index(),strings.LastIndex() The position where the substring appears
strings.Join(a[]string, sep string) Join operation

The byte and rune types in Golang

The elements that make up each string are called “characters,” which can be obtained by traversing or retrieving string elements individually. Characters are enclosed in single quotes (‘), as in:

var a := 'in'
var b := 'x'
Copy the code

There are two types of characters in the Go language:

  1. uint8The type, or byte, representsASCIIA character of.
  2. runeType, representing oneUtf-8 characters.

When you need to handle Chinese, Japanese, or other compound characters, you need to use the rune type. The rune type is actually an INT32.

Go uses a special rune type to handle Unicode, which facilitates Unicode-based text processing, as well as a byte type for default string processing, with performance and scalability benefits.

// Iterate over the string
func traversalString(a) {
	s := Shahe, "hello"
	for i := 0; i < len(s); i++ { //byte
		fmt.Printf("%v(%c) ", s[i], s[i])
	}
	fmt.Println()
	for _, r := range s { //rune
		fmt.Printf("%v(%c) ", r, r)
	}
	fmt.Println()
}
Copy the code

Output:

104 (h) 101 (e) (l) (l) 111 108 108 230 (æ) 178 (o) (squared) 153 (230) (æ) 178 (squared) 179 (after) (h) (e) 108 101 104 108 (l) (l) 111 (o) 27801 (sand) 27827 (river)Copy the code

Since UTF8 encodes a Chinese character in three to four bytes, we cannot simply iterate through a string containing Chinese characters by byte, otherwise we will see the result of the first line in the output above.

At the bottom of the string is an array of bytes, which can be converted to and from [] bytes. A string cannot be modified. A string consists of byte bytes. Therefore, the length of a string is the length of byte bytes. The rune type is used to represent utF8 characters. A rune character consists of one or more bytes.

Modify string

To modify a string, first convert it to []rune or []byte, and then convert it to string. In either case, memory is reallocated and the byte array is copied.

func changeString(a) {
	s1 := "big"
	// Cast
	byteS1 := []byte(s1)
	byteS1[0] = 'p'
	fmt.Println(string(byteS1))

	s2 := "White radish"
	runeS2 := []rune(s2)
	runeS2[0] = 'red'
	fmt.Println(string(runeS2))
}
Copy the code

Type conversions in Golang

The Go language has only cast, not implicit cast. This syntax can only be used when conversions between two types are supported.

The basic syntax for casts is as follows:

T(expression)Copy the code

Where T represents the type to be converted. Expressions include variables, complex operators and function return values.

For example, the Sqrt() function of the Math package is used to calculate the hypotenuse of a right triangle. The Sqrt() function takes in float64, and the variables A and B are int. In this case, you need to cast a and B to float64.

func sqrtDemo(a) {
	var a, b = 3.4
	var c int
	Math.sqrt () receives arguments of type FLOAT64 that need to be cast
	c = int(math.Sqrt(float64(a*a + b*b)))
	fmt.Println(c)
}
Copy the code

exercises

  1. Write code to define an integer, floating point, Boolean, string variable, usingfmt.Printf()collocation%TPrint the values and types of the above variables separately.
  2. Write code to count strings"Hello, the Little Prince of Sand River."The number of Chinese characters.

3. If judgment and for loop

The most commonly used flow control in Go language is if and for, while switch and GOTO are mainly structures created to simplify code and reduce repetitive code, which belong to extended class flow control.

If else

The basic writing method of if condition judgment

The format of if condition judgment in Go language is as follows:

ifexpression1{branch1
} else ifexpression2{branch2
} else{branch3
}
Copy the code

If the result of expression 1 is true, branch 1 is executed; if expression 2 is true, branch 2 is executed; if neither is true, branch 3 is executed. Else if and else in the if judgment are optional and can be selected as required.

The Go language dictates that the open parenthesis {matching an if must be placed on the same line as the if and expression. Placing {elsewhere triggers a compilation error. Similarly, {matching else must be on the same line as else, and else must be on the same line as the curly brace to the right of the previous if or else if.

Here’s an example:

func ifDemo1(a) {
	score := 65
	if score >= 90 {
		fmt.Println("A")}else if score > 75 {
		fmt.Println("B")}else {
		fmt.Println("C")}}Copy the code

If condition judgment special notation

Another special way to judge an if condition is by adding an execution statement to the if expression and then judging the value of the variable. For example:

func ifDemo2(a) {
	if score := 65; score >= 90 {
		fmt.Println("A")}else if score > 75 {
		fmt.Println("B")}else {
		fmt.Println("C")}}Copy the code

Question to consider: what is the difference between the two writing methods?

For (loop structure)

All loop types in the Go language can be done using the for keyword.

The basic format of the for loop is as follows:

forInitial statement; Conditional expression; End statement {loop body statement}Copy the code

The loop body continues to loop until the conditional expression returns false.

func forDemo(a) {
	for i := 0; i < 10; i++ {
		fmt.Println(i)
	}
}
Copy the code

The initial statement of the for loop can be ignored, but the semicolon after the initial statement must be written, for example:

func forDemo2(a) {
	i := 0
	for ; i < 10; i++ {
		fmt.Println(i)
	}
}
Copy the code

The initial and closing statements of the for loop can be omitted, for example:

func forDemo3(a) {
	i := 0
	for i < 10 {
		fmt.Println(i)
		i++
	}
}
Copy the code

This writing is similar to while in other programming languages. After the while, a conditional expression is added, and the loop continues until the conditional expression is satisfied, otherwise the loop ends.

An infinite loop

for{loop body statement}Copy the code

The for loop can be forced out of the loop by the break, goto, return, and Panic statements.

For range(key-value loop)

Go allows for range to iterate over groups, slices, strings, maps, and channels. The return value traversed through for range has the following pattern:

  1. Arrays, slicing, and strings return indexes and values.
  2. Map returns keys and values.
  3. A channel returns only the value within the channel.
s := "Hello one Piece."
for i,v := range d {
    fmt.Printf("%d %c\n",i,v);
}

// Output the result
0 h
1 e
2 l
3 l
4 o
5
789Copy the code

switch case

The switch statement makes it easy to condition a large number of values.

func switchDemo1(a) {
	finger := 3
	switch finger {
	case 1:
		fmt.Println("Thumb")
	case 2:
		fmt.Println("Finger")
	case 3:
		fmt.Println("Middle finger")
	case 4:
		fmt.Println("Ring finger")
	case 5:
		fmt.Println("Little finger")
	default:
		fmt.Println("Invalid input!")}}Copy the code

The Go language specifies that each switch can have only one default branch.

A branch can have multiple values, separated by commas.

func testSwitch3(a) {
	switch n := 7; n {
	case 1.3.5.7.9:
		fmt.Println("Odd")
	case 2.4.6.8:
		fmt.Println("Even")
	default:
		fmt.Println(n)
	}
}
Copy the code

Branching can also use expressions, which do not need to be followed by a variable. Such as:

func switchDemo4(a) {
	age := 30
	switch {
	case age < 25:
		fmt.Println("Study hard.")
	case age > 25 && age < 35:
		fmt.Println("Get back to work.")
	case age > 60:
		fmt.Println("Enjoy it.")
	default:
		fmt.Println("It's good to be alive")}}Copy the code

Fallthrough syntax can execute the next case of a case that meets the condition. It is designed to be compatible with CASES in C language.

func switchDemo5(a) {
	s := "a"
	switch {
	case s == "a":
		fmt.Println("a")
		fallthrough
	case s == "b":
		fmt.Println("b")
	case s == "c":
		fmt.Println("c")
	default:
		fmt.Println("...")}}Copy the code

Output:

a
b
Copy the code

Goto (jump to specified label)

The GOTO statement makes unconditional jumps between codes through tags. The goto statement can be helpful in breaking out of loops quickly and avoiding repeated exits. The use of goto statements in Go simplifies the implementation of some code. For example, to exit a double-nested for loop:

func gotoDemo1(a) {
	var breakFlag bool
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			if j == 2 {
				// Set the exit label
				breakFlag = true
				break
			}
			fmt.Printf("%v-%v\n", i, j)
		}
		// Outer for loop judgment
		if breakFlag {
			break}}}Copy the code

Using the goto statement simplifies code:

func gotoDemo2(a) {
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			if j == 2 {
				// Set the exit label
				goto breakTag
			}
			fmt.Printf("%v-%v\n", i, j)
		}
	}
	return
	/ / label
breakTag:
	fmt.Println("End for loop")}Copy the code

Break (to break out of the loop)

The break statement terminates blocks of code for, switch, and SELECT.

The break statement can also be followed by a label to exit the code block corresponding to a label. The label must be defined on the corresponding for, switch, and SELECT code blocks. Here’s an example:

func breakDemo1(a) {
BREAKDEMO1:
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			if j == 2 {
				break BREAKDEMO1
			}
			fmt.Printf("%v-%v\n", i, j)
		}
	}
	fmt.Println("...")}Copy the code

Continue (continue the next loop)

The continue statement terminates the current loop and begins the next iteration of the loop. It is only used within the for loop.

When a label is added after the continue statement, the loop for the label begins. Such as:

func continueDemo(a) {
forloop1:
	for i := 0; i < 5; i++ {
		// forloop2:
		for j := 0; j < 5; j++ {
			if i == 2 && j == 2 {
				continue forloop1
			}
			fmt.Printf("%v-%v\n", i, j)
		}
	}
}
Copy the code

Go language basic Grammar (Middle)