Go Language Basic Grammar
Article Directory
1. Notes
- When we write code, this happens for a long time. The code that has just been written feels that the logic is very clear. How can I be so good? When I look at this code after a while, I will have a question, who the hell wrote this code! So in order to prevent yourself from not being able to understand your own code, or if you want to show the code you wrote to others, at this time, we need to explain it!
Note: You can understand that it is written for people to read, and the machine will not execute this line of statement.
- The main function of comments is to enhance the readability of the code and not to participate in all functions of the program. Comments in Go language are mainly divided into two categories.
1. Single-line comments
package main
// 双斜杠表示单行注释,程序不会执行这行语句,这是写给自己或他人看的
import "fmt"
func main() {
fmt.Printf("helloword!")
}
2. Multi-line comments
package main
/*
杠星 星杠表示多行注释,在二者之间的范围内可以换行写多行注释
*/
import "fmt"
/*
这是一个main函数,这是go语言启动的入口
*/
func main() {
// fmt.Printfln:打印一行内容,然后执行完成后进行换行
fmt.Printfln("hello,word!")
}
Developing a good habit of writing notes is convenient for yourself to read and for others to read
2. Variables
- In mathematics, a variable represents a variable number that has no fixed value. For example, x=1, x= 2;
- Literal understanding: A variable is a quantity that changes.
- For example, I set a variable called name, which is represented in the Go language as follows: this value can be Zhang San, Li Si, Wang Wu, or your name. So here, this name is a variable, the amount that can change.
// 这里的等于是赋值,就是把等号右边的值,赋值给左边变量的意思
var name string = "guan"
In addition to the name, we have written other things here, such as what are var and string for? Next, let’s take you to understand the definition of variables in the go language and some data types in the go language (such as the name name above, which is a string type. We sometimes need to represent numbers, so there are also digital types, etc., which will be further understood later).
1. Definition of variables
- Go language is a statically typed language, that is, we need to define all types explicitly. Regardless of other types here, first understand string and use it to represent half a character.
- In Go language, we declare a variable generally enough to use
var
keywords:
var name type
- The first var is the keyword for declaring a variable. It is a fixed way of writing. To declare a variable, you need a var.
- The second name is the name of the variable. You can give it a name according to your needs for subsequent use.
- The second type is used to represent the type of the variable.
Take a chestnut:
// 定义一个字符串变量,name
var name string
// 定义一个数字类型变量 age
var age int
If you have learned Java, C or other programming languages before, it will be uncomfortable to see such an operation for the first time. The Go language is different from many programming languages. It puts the type of the variable after the variable name when declaring the variable. This is to avoid the ambiguous declaration form like the C language, for example: int *a, b; where only a is a pointer and b is not. If you want these two variables to be pointer variables, you need to write them separately. In Go, however, you can and easily declare both to be of type:
var a,b *int
The variable naming rules follow the camel naming method, that is, the first word is lowercase, and the first letter of each new word is capitalized, for example: helloWord and guanGuan. .
The standard format for variable definitions is
var 变量名 变量类型
A variable declaration begins with the keyword var, followed by the variable type, and there is no need for a semicolon at the end of the line.
We sometimes define variables in batches. If it is troublesome to define them separately every time, the Go language supports batch definition variables using the key var and brackets, which can put a group of variable definitions together.
var (
name string
age int
addr string
)
The declaration statement of the form is often used where the type of the variable needs to be explicitly specified, or where the initial value does not matter because the variable will be reassigned later. When a variable is declared, if it is not explicitly assigned a value, the system automatically assigns it a zero value of that type:
- The default values for integer and float variables are 0 and 0.0
- The default value of a string variable is the empty string.
- The default value of Boolean variables is false.
- Slices, functions, and pointer variables default to null
fmt.Printf(name, age, addr)
2. Variable initialization
Standard format for variable initialization
var 变量名 类型 = 值(表达式)
For example, if I want to define some information about guan, I can express it like this
var name string = "guan"
var age int = 18
fmt.Printf("name:%s,age:%d", name, age)
The name and age here are variable names, the type of name is string, and the type of age is int. Their values are guan and 18 respectively
Short variable declaration and initialization
name := "guanGuan"
age :=18
fmt.Printf("name:%s,age:%d", name, age)
This is the derivation statement written in the Go language. The compiler will automatically infer the corresponding type of the lvalue based on the rvalue type. It can automatically deduce some types, but the use is also limited;
- Define a variable while explicitly initializing it.
- Data type cannot be provided.
- Can only be used inside a function. can not be defined everywhere
Because of its brevity and flexibility, short variable declarations are widely used for most local variable declarations and initializations.
Note: Since := is used instead of = for assignment, the lvalue variable written in the derivation statement must be a variable that has not been defined. If defined, a compilation error will occur.
// 定义变量 name
var name string
// 定义变量 name,并赋值为"guanGuan"
name := "guanGuan"
The compilation will report an error, and the information is as follows: no new variables on left side of := means that no new variables appear on the left side of ":=", which means that the variable on the left side of ":=" has been declared.
3. Understand variables (memory addresses)
var num int
num = 1000
fmt.Printf("num的值:%d,内存地址:%p\n", num, &num)
num = 2000
fmt.Printf("num的值:%d,内存地址:%p\n", num, &num)
4. Variable exchange
package main
import "fmt"
func main() {
/*
在编程中,最简单的算法就是变量的交换,但是一般常见的方式就是定义中间变量
var a int = 100
var b int = 2oo
var t int
t = a
a = b
a = t
fmt.Println(a,b)
*/
var a int = 100
var b int = 200
fmt.Printf("交换前的变量a=%d,b=%d\n", a, b)
// 在Go语言中,可以直接用这样的方式实现值得交换,无需中间变量
b, a = a, b
fmt.Printf("交换后的变量a=%d,b=%d", a, b)
}
output
5. Anonymous variables
Anonymous variables are characterized by an underscore "" , " " itself is a special identifier, known as a blank identifier. It can be used for variable declaration or assignment like other identifiers (any type can be assigned to it), 但任何赋给这个标识符的值都将被抛弃
so these values cannot be used in subsequent codes, nor can this identifier be used as a variable to assign or operate on other variables. When using anonymous variables, you only need to use an underscore to replace the variable declaration.
For example:
package main
import "fmt"
/*
定义一个test函数,它会返回两个int类型的值,每次调用将会返叵 100 和 200 两个数值、这里我们先不只管 函数的定义,后面会讲解。89我们用这个函数来理解这个匿名变量。
*/
func test()(int, int) {
return 100, 200
}
func main(){
a,_:= test()
_, b := test()
fmt.Println(a, b) //输出的结果100,200
// 在第一行代码巾,我们只需要获取第一个返叵值,所以第二个返回值定义为匿名交量
// 在第二行代码巾,我们只需要获取第二个返叵值,所以第一个返回值定义为匿名变量
}
- During compilation, a variable, type, or method without a name may be encountered. Although this is not necessary, sometimes doing so can greatly enhance the flexibility of the code, and these variables are collectively referred to as anonymous variables.
- Anonymous variables do not occupy memory space and do not allocate memory. Between anonymous variables and anonymous variables will not be unusable due to multiple declarations.
6. The scope of variables
A variable (constant, type or function) has a certain scope in the program, called scope.
Understanding the scope of variables is very important for us to learn the Go language, because the Go language will check whether each variable has been used at compile time. Once an unused variable appears, a compilation error will be reported. If the scope of variables cannot be resolved, it may cause some unknown compilation errors.
local variable
The variables declared in the function body are called local variables, and their scope is only in the function body. The parameters and return value variables of the function are all local variables.
package main
import "fmt"
// 全局变量
var name string = "guanGuan"
func main() {
//局部变量
var age int = 18
var name string = "Guan"
fmt.Println(name, age)
}
func test() {
fmt.Println(name)
}
global variable
Variables declared outside the function are called global variables. Global variables only need to be defined in one source file, and they can be used in all source files. Of course, source files that do not contain this global variable need to use the "import" key to import the source file where the global variable is located before using this global variable.
Global variable declarations must begin with the var keyword, and the first letter of a global variable must be capitalized if you want to use it in an external package.
//声明全局变量
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) //a = 3, b = 4, c = 7
}
In a Go language program, the names of global variables and local variables can be the same, but the local variables in the function body will be given priority.
package main
import "fmt"
//声明全局变量
var a float32 = 3.14
func main(){
//声明局部变量
var a int = 3
fmt.Printf("a = %d\n", a) // a = 3
}
3. Constants
1. Definition of constant: const
常量是一个简单值的标识符,在程序运行时,不会被修改的量。
- The data types in constants can only be Boolean, numeric (integer, floating point, and complex) and character
const identifier [type] = value
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"
Multiple declarations of the same type can be abbreviated as:
const c_name1, c_name2 = value1, value2
The following example demonstrates the use of constants:
package main
func main() {
// 常量不能被修改的量,否则会报错
const URL string = "www.baidu.com"
URL = "www.guan.com"
}
output
package main
import "fmt"
func main() {
const URL1 string = "www.baidu.com" // 显式定义
const URL2 = "www.guan.com" // 隐式定义
const a,b,c = 3.14,"guanGuan",true //同时定义多个常量
fmt.Println(URL1)
fmt.Println(URL2)
fmt.Println(a,b,c)
}
output
2.iota (special constant)
-
iota, a special constant, can be considered as a constant that can be modified by the compiler. iota is a constant recognizer of go language
-
iota will be reset to 0 when the const keyword appears (before the first line inside const), and each new line of constant declaration in const will make iota count once (iota can be understood as the row index in the const statement block).
iota can be used as enumeration value:
const (
a = iota
b = iota
c= iota
)
The first iota is equal to 0, and whenever iota is used in a new line, its value will automatically increase by 1; so a=0, b=1, c=2 can be abbreviated as follows:
package main
import "fmt"
func main() {
const (
// 一组常量中,如果某个常量没有初始值,默认和上一行一致
a = iota //iota=0
b //iota=1
c //iota=2
d = "hello,guan" // hello,guan iota=3
e // hello,guan iota=4
f = 100 // 100 iota=5
g // 100 iota=6
h = iota //iota=7
i //iota=8
)
const (
j = iota // iota=0
k = iota // iota=1
)
fmt.Println(a, b, c, d, e, f, g, h, i, j, k)
}
4. Basic data types
Go language is a statically typed programming language. In Go programming language, data types are used to declare functions and variables. The emergence of the data type is to divide the data into data with different required memory sizes. When programming requires large data, it is necessary to apply for a large memory, which can fully utilize the memory. When the compiler is talking about compiling, it needs to know the type of each value, so that the compiler knows how much memory to allocate for this value, and knows what the allocated memory represents.
1. Boolean type
Boolean values can only be the constant true or false. Take a simple chestnut:
package main
import "fmt"
func main() {
// var 变量名 数据类型
// bool: true false
var isFlag bool
var b1 bool = true
var b2 bool = false
fmt.Println(isFlag) //如果不进行初始赋值,则默认值为false
fmt.Printf("%T,%t\n", b1, b1)
fmt.Printf("%T,%t\n", b2, b2)
}
2. Numeric
Integer type int and floating-point type loat32, foat64, Go language supports integer and floating-point numbers, and supports complex numbers, and the operation of the bit adopts complement code.
Go also has architecture-based types, for example: uint unsigned, int signed
serial number | type and description |
---|---|
1 | uint8 Unsigned 8-bit integer (0 to 255) |
2 | uint16 Unsigned 16-bit integer (0 to 65535) |
3 | uint32 Unsigned 32-bit type (0 to 4294967295) |
4 | uint64 Unsigned 64-bit integer (0 to 18446744073709551615) |
5 | int8 Signed 8-bit integer (-128 to 127) |
6 | int16 signed 16-bit integer (-32768 to 32767) |
7 | int32 signed 32-bit integer (-2147483648 to 2147483647) |
8 | int64 Signed 64-bit integer (-9223372036854775808 to 9223372036854775807) |
package main
import "fmt"
func main() {
// 定义一个整型
// byte uint8
// rune int32
// int int64
var age int = -100
var i1 int8
var i2 uint8
i1 = 66
i2 = 188
fmt.Printf("%T,%d\n",age,age)
fmt.Println(i1)
fmt.Println(i2)
}
floating point
serial number | type and description |
---|---|
1 | float32 IEEE-754 32-bit floating-point number |
2 | float64 IEEE-754 64-bit floating point number |
3 | complex64 32-bit real and imaginary numbers |
4 | complex128 64-bit head and imaginary numbers |
package main
import "fmt"
func main() {
var f1 float32
f1 = 3.14
var f2 float64
f2 = 5.12
// %f 默认保留小数点后6位,.2f%就是保留2位,.3f%就是保留3位
fmt.Printf("%T,%.3f\n", f1, f1)
fmt.Printf("%T,%f\n", f2, f2)
}
output
1. A brief description of the storage form of floating point numbers in the machine, floating point = sign bit + exponent bit + mantissa bit
2. The mantissa part may be lost, resulting in a loss of precision. -123.0000901
package main
import "fmt"
func main() {
// float64 尽量使用 float64 来定义浮点类型的小数
var num1 float32 = -123.1234567
var num2 float64 = -123.1234567
fmt.Println("num1=", num1, "num2=", num2)
}
- Explanation: The precision of float64 is more accurate than that of float32
- Explanation: If we want to save a number with high precision, we should choose float64
3. The storage of floating-point type is divided into two parts: sign bit + exponent bit + mantissa bit. During the storage process, the precision will be lost,
4. The floating-point type of golang defaults to float64 type
5. Normally, float64 should be used because it is more accurate than float32
Other more numeric types are listed below:
serial number | type and description |
---|---|
1 | byte like uint8 |
2 | rune similar to int32 |
3 | uint 32 or 64 bit |
4 | int is the same size as uint |
5 | uintptr unsigned integer, used to store a pointer |
3. String type
import "fmt"
func main() {
var str string
str = "helloWorld!"
fmt.Printf("%T,%s\n", str, str)
//单引号 字符 ,整型-ASCII字符码
x1 := 'A'
x2 := "A"
x3 := '关'
// 拓展
// 编码表 ASCII 字符码
// 所有的中国字的编码表:GBK
// 全世界的编码表:Unicode 编码表
fmt.Printf("%T,%d\n", x1, x1)
fmt.Printf("%T,%s\n", x2, x2)
fmt.Printf("%T,%s\n", x3, x3)
}
package main
import "fmt"
func main() {
var str1, str2, str3 string
str1 = "hello"
str2 = "guan"
str3 = ","
// 字符串的连接 用 + 号
fmt.Println(str1 + str3 + str2)
// 转义字符 \
fmt.Println("hello\\guan")
fmt.Println("hello\"guan")
fmt.Println("hello\nguan") // \n 换行
fmt.Println("hello\tguan") // \t 制表符
}
output
4. Data type conversion
Values of one type can be converted to values of another type when necessary and feasible. Since there is no implicit type conversion in the Go language, all type conversions must be explicitly declared:
valueofTypeA = typeA (valueofTypeB)
value of type A = type A (value of type B)
func main() {
a := 5.0 // float64
b := 8 // int
//需求:将int类型的 b 转化为 float64 类型
c := float64(b)
d := int(a)
// 整型不能转换为bool类型
//e := bool(b)
//fmt.Printf("%T,%f\n", e, e)
fmt.Printf("%T,%f\n", c, c)
fmt.Printf("%T,%d\n", d, d)
}
output
A type conversion can only succeed if the definition is correct, such as converting from a type with a smaller value range to a type with a larger value range (converting int16 to int32). When converting from a type with a larger value range to a type with a smaller range (converting int32 to int16 or converting float32 to int), precision loss (truncation) will occur.
5. Operators
1. Arithmetic operators
The following table lists all the arithmetic operators of Go language. Assume A has a value of 1 and B has a value of 2.
operator | describe | example |
---|---|---|
+ | add up | A+B output result 3 |
- | Subtract | AB output result -1 |
* | multiplied | A*B output result 2 |
/ | to divide | A/B steal result 0 |
% | Surplus | A % B lose mountain result 1 |
++ | self-increment | A++ output result 2 |
– | Decrement | A – output result 1 |
package main
import "fmt"
func main() {
var a int = 1
var b int = 2
// + - * / % ++ --
fmt.Println(a + b)
fmt.Println(a - b)
fmt.Println(a * b)
fmt.Println(a / b)
fmt.Println(a % b)
a++
fmt.Println(a)
a--
fmt.Println(a)
}
output
2. Relational operators
The following table lists all relational operators in Go language. Assume the value of A is 1 and the value of B is 2.
operator | describe | example |
---|---|---|
== | Checks if two values are equal, returns True if equal, False otherwise | (A == B) is False |
!= | Checks if two values are equal, returns True if not equal, otherwise returns False | (A!=B) is True |
> | Checks if the value on the left is greater than the value on the right, returns True if it is, False otherwise | (A > B) is False |
< | Check if the value on the left is less than the value on the right, if so return True, otherwise return False | (A < B) is True |
>= | Check if the value on the left is greater than or equal to the value on the right, return True if it is, otherwise return False | (A > B) is False |
<= | Check if the value on the left is less than the value on the right, if so return True, otherwise return False | (A<=B) is True |
package main
import "fmt"
func main() {
var a int = 1
var b int = 2
// ==等于 =赋值
// 关系运算符 返回结果都是 bool值
fmt.Println(a == b)
fmt.Println(a != b)
fmt.Println(a > b)
fmt.Println(a < b)
fmt.Println(a >= b)
fmt.Println(a <= b)
}
output result
3. Logical operators
The following table lists all logical operators in Go language. Suppose the value of A is True and the value of B is False.
operator | describe | example |
---|---|---|
&& | Logical AND operator. Condition True if both operands are True, otherwise False | (A && B) One False |
|| | Logical OR operator. The condition is True if both operands have a True, otherwise it is False. | (A || B) is True |
! | Logical NOT operator. The logical NOT condition is False if the condition is True, otherwise it is True. | !(A && B) One True |
package main
import "fmt"
func main() {
var a bool = true
var b bool = false
// 逻辑与 && 要左右两边的表达式同时为真,才执行,结果才为真,否则为假
// 关系运算符 返回结果都是 bool值
fmt.Println(a && b)
// 逻辑或 || 只要其中有一个为真,则为真,全为假则为假
fmt.Println(a || b)
// !为逻辑非,即取反,结果相反
// a = true
// b = false
fmt.Println(!a)
fmt.Println(!b)
}
output result
4. Bitwise operators
The bitwise operators supported by the Go language are shown in the table below. Let A be 60 and B be 13:
operator | describe | example |
---|---|---|
& | The bitwise AND operator "&" is a binary operator. If both are 1, the result is 1, otherwise 0 | (A & B) The result is 12, which is 0000 1100 in binary |
| | The bitwise OR operator "|" is the double month operator. Both are 0 and the result is 0, otherwise it is 1 | (A|B)结果为 61,二进制为 0011 1101 |
^ | 按位异或运算符"^"是双目运算符。不同则为1,机同为0 | (A^B)结果为49,二进制为 0011 0001 |
&^ | 位清空,a&^b,对于b上的每个数值,如果为0,则取a对应位上的数值,如果为1,则取0 | (A &^ B) 结果为 48,二进制为 0011 0000 |
<< | 左移运算符"<<“是双目运算符。左移n位就是乘以2的n次方。其功能把”<<“左边的运算数的各二进位全部左移若干位,由”<<"右边的数指定移动的位数,高位丢弃,低位补0 | A<<2 结果为 240,二进制为 1111 0000 |
>> | 右移认算符">>“是双目运算符。右移n位就是除以2的n次方。其功能是把”>>“左边的运算数的各二进制文全部右移若干位,”>>"右边的数指定移动的位数 | A >> 2 结果为 15,二进制为0000 1111 |
package main
import "fmt"
func main() {
// 二进制 0 1 逢二进一
// 位运算:二进制上的 0 false 、 1 true
// 逻辑运算符: && 只要有一个为假,则为假、 || 只要有一个为真,则为真
// a 60 0011 1100
// b 13 0000 1101
// --------------------------
// & 0000 1100 同时满足
// | 0011 1101 一个满足就行
// ^ 0011 0001 不同为1,相同为0
// << 2
// >> 2
var a uint = 60
var b uint = 13
// 位运算
var c uint = 0
c = a & b //位运算
fmt.Printf("%d,二进制%b", c, c) // 0000 1100
fmt.Println()
c = a | b //位运算
fmt.Printf("%d,二进制%b", c, c) // 0011 1101
fmt.Println()
c = a ^ b //位运算
fmt.Printf("%d,二进制%b", c, c) // 0011 0001
fmt.Println()
// 60 0011 1100
c = a << 2
fmt.Printf("%d,二进制%b", c, c) //
fmt.Println()
a = 60
c = a >> 2
fmt.Printf("%d,二进制%b", c, c) //
}
输出
5.赋值运算符
下表列出了所有Go语言的赋值认算符。
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符,将一个表达式的值赋给一个左值 | C=A+B将 A+B表达式结果赋值给C |
+= | 相加后赋值 | B+=A等于B=B+A |
-= | 相减后再赋值 | B-=A 等于 B=B-A |
*= | 相乘后再赋值 | C*=A等于C=C*A |
/= | 相除后由赋值 | C/=A等于C= C/A |
%= | 求余后再赋值 | C%=A 等于 C= C % A |
<<= | 左移后赋值 | C<<=2等于C=C<<2 |
>>= | 右移后赋值 | C>>=2等于C=C>>2 |
&= | 按位与后赋值 | C&=2 等于C=C&2 |
٨= | 按位异或后赋值 | C^=2 等于C=C^2 |
| = | 按位或后赋值 | C|=2等于 C = C|2 |
package main
import "fmt"
func main() {
var a int = 21
var c int
// 将等号右边的值,赋值给左边
c = a
fmt.Printf("第 1 行 = 运算符实例,c 值为 = %d\n", c)
c += a
fmt.Printf("第 2 行 += 运算符实例,c 值为 = %d\n", c)
c -= a
fmt.Printf("第 3 行 -= 运算符实例,c 值为 = %d\n", c)
c *= a
fmt.Printf("第 4 行 *= 运算府实例,c 值为 = %d\n", c)
c /= a
fmt.Printf("第 5 行 /= 运算符实例,c 值为 = %d\n", c)
c = 200
c <<= 2
fmt.Printf("第 6行 <<= 运算符实例,c值为 = %d\n", c)
c >>= 2
fmt.Printf("第 7 行 >>= 运算符实例,c 值为 = %d\n", c)
c &= 2
fmt.Printf("第 8 行 &= 运算符实例,c 值为 = %d\n", c)
c ^= 2
fmt.Printf("第 9 行 ^= 运算符实例,c 值为 = %d\n", c)
c |= 2
fmt.Printf("第 10 行 |= 运算符实例,c 值为 =%d\n", c)
}
输出
6.其他运算符
下表列出了Go语言的其他运算符
运算符 | 描述 | 实例 |
---|---|---|
& | 返回变量存储地址 | &a;将给出变量的实际地址 |
* | pointer variable | *a; is a pointer variable |
package main
import "fmt"
func main() {
var a int = 6
var b int32
var c float32
var ptr *int
/* 运算符实例 */
fmt.Printf("第 1 行 a 变量类型为 = %T\n", a)
fmt.Printf("第 2 行 b 变量类型为 = %T\n", b)
fmt.Printf("第 3 行 c 变量类型为 = %T\n", c)
/* & 和 * 运算符实例 */
ptr = &a /* 'ptr' 包含了 'a' 变量的地址 */
fmt.Printf("a 的值为 = %d\n", a)
fmt.Printf("ptr 的值为 = %p\n", ptr)
fmt.Printf("ptr 的值为 = %d\n", *ptr)
}
output
6. Keyboard input and output
package main
import "fmt"
func main() {
var name string
var phoneNumber string
// 定义了两个变量,想用键盘来输入这两个变量
//fmt.Println() //打印并换行
//fmt.Printf() //格式化输出
//fmt.Print() //打印输出
fmt.Println("请输入姓名和手机号码:")
// 变量去地址 &变量
// 指针、地址来修改和操作变量
// Scanln 阻塞等待从键盘输入
fmt.Scanln(&name, &phoneNumber)
fmt.Println("name:", name)
fmt.Println("phoneNumber:", phoneNumber)
// fmt.Scanln() //接收输入并换行
// fmt.Scanf() // 接收输入,格式化输入
// fmt.Scan() // 接收输入
}
output