一 基本数据类型和操作符
- 文件名&关键字&标识符。
- Go程序基本结构。
- 常量和变量。
- 数据类型和操作符。
- 字符串类型。
1 文件名&关键字&标识符
- 所有go源码以.go结尾。
- 标识符以字母或下划线开头,不能以数字开头,大小写敏感。
- _是特殊标识符叫匿名变量,用来忽略结果,表示舍弃该值,一般配合函数返回值才有优势。
- 保留关键字。
下面对部分常用的关键字进行解释:
-
1) ◼ var和const :变量和常量的声明。例如变量的定义,var varName type 或者 varName : = value。
-
2)◼ package and import: 包和导入。
-
3)◼ func: 用于定义函数和方法。
-
4)◼ return :用于从函数返回。
-
5)◼ defer someCode :在函数退出之前执行。
-
6)◼ go : 用于并行。
-
7)◼ select 用于选择不同类型的通讯。
-
8)◼ interface 用于定义接口。
-
9)◼ struct 用于定义抽象数据类型。
-
10)◼ break、case、continue、for、fallthrough、else、if、switch、goto、default 流程控制。
-
11)◼ fallthrough的用法注意总结 [推荐阅读https://blog.csdn.net/ajdfhajdkfakr/article/details/79086125]。
◼ 1.加了fallthrough后,会直接运行【紧跟的后一个】case或default语句,不论条件是否满足都会执行。
◼ 2.加了fallthrough语句后,【紧跟的后一个】case条件不能定义常量和变量。
◼ 3.执行完fallthrough后直接跳到下一个条件语句,本条件执行语句后面的语句不执行。
◼ 4.fallthrough 语句应该是 case 子句的最后一个语句,否则会报错fallthrough statement out of place。 -
12)◼ chan用于channel通讯。
-
13)◼ type用于声明自定义类型。
-
14)◼ map用于声明map类型数据。
-
15)◼ range用于读取slice、map、channel数据。
2 Go程序的基本结构1
package main
import “fmt”
func main() {
fmt.Println(“hello, world”)
}
- 任何一个代码文件隶属于一个包
- import 关键字,引用其他包:
import(“fmt”)
import(“os”)
通常习惯写成:
import (
“fmt”
“os”
)
- golang可执行程序,package main,并且有且只有一个main入口函数。
- 包中函数调用:
a. 同一个包中函数,直接调用。
b. 不同包中函数,通过包名+点+函数名进行调用,例如fmt.xxx()。 - 包访问控制规则:
a. 大写意味着这个函数/变量是可导出的。
b. 小写意味着这个函数/变量是私有的,包外部不能访问。
例如:calc目录有3个go文件,这3个文件都是calc包。main目录有main.go文件,是main包,然后main.go引入calc包的一个函数,例如引用add.go的Add函数,当将名字Add改成add,那么main.go会访问失败。
编译器会这样报错:
3 函数声明和注释
1. 函数声明: func 函数名字 (参数列表) (返回值列表){}
举例:
- 注释,两种注释,单行注释: // 和多行注释 /* */。
4 常量
- go变量的声明使用var,而常量使用const 修饰,代表永远是只读的,不能修改。
例如:
var a int = 10
const b int = 20
- const 只能修饰boolean,number(int相关类型、浮点类型、complex)和string。
- 语法:const identifier [type] = value,其中type可以省略。
例如:
const b = 20
5 下面全面总结go的变量、常量的定义方法:
- 1)单个变量、常量的声明、初始化。
- 2)多个同类型的变量、常量的声明、初始化。
- 3)多个不同类型的变量、常量的声明、初始化。
package main
import "fmt"
func main(){
// 1. 单个变量、常量的声明、初始化。
// 1)变量
var a int // 声明,再进行初始化
a = 10
var b int = 20 // 声明的同时进行初始化
//var b = 20 // int可以省略
c := 30 // 使用自动推导类型进行声明和初始化,在使用自动推导类型时,必须赋值
// 2)常量。变量使用var关键字,常量使用const。
//const x int
//x = 10 // error,常量声明时必须初始化。
const y int = 20
//const z := 30 // error,常量的自动推导类型时,不能使用:=的方式,直接=即可。
const z = 30
fmt.Printf("a=%d,b=%d,c=%d\n", a, b, c)
fmt.Printf("y=%d,z=%d\n", y, z)
// 2. 多个同类型的变量、常量的声明、初始化。
// 1)变量
var aa, bb int
aa, bb = 10, 20
var cc, dd = 30, 40
ee, ff := 50, 60
// 2)常量
const xx, yy int = 20, 30
const zz, vv = 20, 30
fmt.Printf("aa=%d,bb=%d,cc=%d,dd=%d,ee=%d,ff=%d\n", aa, bb, cc, dd, ee, ff)
fmt.Printf("aa=%d,bb=%d,cc=%d,dd=%d\n", xx, yy, zz, vv)
// 3. 多个不同类型的变量、常量的声明、初始化。
// 1)变量
// 正常定义不同类型的方法
var A int = 10
var B float64 = 10.1
// 那么可以写成:
var(
AA int
BB float64
)
AA = 2
BB = 10.2
// 同时也可以进行赋值
var(
AAA int = 3
BBB float64 = 10.3
)
// 常量
// 正常定义不同类型的方法
const O int = 1
const P float64 = 1.1
// 那么声明可以写成(因为常量必须在声明时赋值,所以不能缺少赋值):
const(
OO int = 2
PP float64 = 2.2
)
// 常量可以省略类型type
const(
OOO = 3
PPP float64 = 3.3
)
fmt.Printf("A=%d,B=%f,AA=%d,BB=%f,AAA=%d,BBB=%f\n", A, B, AA, BB, AAA, BBB)
fmt.Printf("O=%d,P=%f,OO=%d,PP=%f,OOO=%d,PPP=%f\n", O, P, OO, PP, OOO, PPP)
// 所以可以总结go的变量、常量的定义方法:
// 1)变量有3种:1)开始只声明,后赋值;2)声明的同时并赋值;3)使用自动推导类型,但必须有值才能推导。
// 2)常量有2种:1)const varName varType = value;2)省略数据的类型让其自动推导,const varName = value。
}
6 值类型和引用类型
-
值类型:变量直接存储值,内存通常在栈中分配。
-
引用类型:变量存储的是一个地址,这个地址存储最终的值。内存通常在堆上分配。通过GC回收。
-
值类型:基本数据类型int、float、bool、string以及数组和struct。
-
引用类型:指针、slice、map、chan等都是引用类型。
代码举例(对比C/C++的值和引用还是简单很多了):
package main
import (
"fmt"
)
func modify(a int) {
a = 10
return
}
func modify1(a *int) {
*a = 10
}
func main() {
// 1. 打印观察不同类型是值类型还是引用类型
a := 5
b := make(chan int, 1)
fmt.Println("a=", a) // output: 5。 基本类型是值类型,打印出来是数值
fmt.Println("b=", b) // output: 0xc00001a0e0。通道是引用类型,打印出来是地址
// 2. 值传递不会修改源变量,地址会。
modify(a)
fmt.Println("a=", a) // output: 5。
modify1(&a)
fmt.Println("a=", a) // output: 10。
}
7 变量的作用域
- 在函数内部声明的变量叫做局部变量,生命周期仅限于函数内部。
- 在函数外部声明的变量叫做全局变量,生命周期作用于整个包,如果是大写的,
则作用于整个程序。
例如:
package main
import "fmt"
// 全局变量,因为名字是小写所以作用域为整个main包;若是大写则是整个程序。
var a = "G"
func main() {
n()
m()
n()
// {
// var aa int
// }
//fmt.Println(aa) // error,和C一样,aa这样是未定义的
}
func n() {
fmt.Println(a)
}
func m() {
a := "O" // 这样写,代表在本函数新定义了一个变量a,是局部变量。所以这里修改的是局部变量。main依次输出:G O G
//a = "O" // 这样写,代表修改的是全局变量。main依次输出:G O O
fmt.Println(a)
}
8 数据类型和操作符
- bool类型,只能存true和false。
- 数字类型,主要有int、int8、int16、int32、int64、uint8、uint16、uint32、uint64、
float32、float64。 - 类型转换,go的类型转换严格,不支持隐式转换,必须显示转换。并且和C/C++一样,大转小会造成数据丢失,小转大则不会。
例如:
var a int
var b int32
a = 15
//b = a + a // compiler error. 应该写成b = int32(a + a)
b = b + 5 // ok
fmt.Println(a, b) // 15 5
package main
import "fmt"
func main() {
var n int16 = 34
var m int32
m = int32(n) // 小转大,不会造成数据丢失
var x int16
var y int32 = 800000
x = int16(y) // 大转小,数据丢失
fmt.Printf("n: %d, m: %d\n", n, m) // 34 34
fmt.Printf("x: %d, y: %d\n", x, y) // 两个值肯定不一样,即数据丢失了
}
-
字符类型:var a byte。例如var a byte = ‘c’。类似C/C++的char。
-
字符串类型: var str string。例如var str = “hello world”,string可以省略。类似C的char*,C++的string对象。
字符串的两种表示方式: 1)双引号 “”。2)反引号``。
9数据类型和操作符
- 逻辑操作符: == 、!=、<、<=、> 和 >=。
- 数学操作符:+、-、*、/等等。C语言叫算术运算符。