- 值类型:数值类型,bool,string,数组,struct结构体
变量直接存储值,内存通常在栈中分配, 修改值, 不会对源对象产生影响 - 引用类型:指针,slice切片,管道chan,map,interface
变量存储的是一个地址,这个地址对应的空间才真正存储数据值,内存通常在堆上分配,当没有任何变量引用这个地址时,该地址对应的数据空间就成为一个垃圾,由GC来回收,同时,当地址指向的数据值改变时,会对源对象产生影响。
局部变量
var `变量名` `类型` = `参数` var `变量名` = `参数` `变量名` := `参数`
全局变量
var (
`变量名` = `参数`
)
整数类型:int8,int16,int32,int64,rune,byte,uint8,uint16,uint32,uint64
小数类型:float32,float64
''用于表示字符类型
""用于表示字符串类型
var str1 string = "123"+ "456"5.基本数据类型转换:
在go语言中转换数据类型需要显式转换
将float64类型转换为float32类型
var n1 float64 = 3.2 n2 := float32(n1)6.基本数据类型转换为string数据类型:
第一种:fmt.Sprintf
num1 := 3
string1 := fmt.Sprintf("%d",num1)
第二种:strconv包函数
str1 := strconv.FormatInt(num1,10) #第一个参数是变量,第二个参数是这个变量的类型 2是2进制数,10是10进制数 具体看官方文档
第三种:strconv.Itoa
str1 := strconv.Itoa(num1) #num1是int类型7.string数据类型转换为基本数据类型:
var str1 string = "1" //bool b,_ := strConv.ParseBool(str1) //int b,_ := strConv.ParseInt(str1,10,0) //float b,_ := strConv.ParseFloat(str1,64)8.指针:
指针变量存储的是一个地址,这个地址指向的空间存的才是值
前面带*表示ptr是一个指针
使用&可以查看num的指针值
使用&ptr可以直接修改num的值
num := 1 var ptr *int = &num &ptr = 29.接收键盘输入语句:
var name string
fmt.Scanln(&name)
或
fmt.Scanf("%s",&name)
10.分支结构
除了我们常用的if else分支结构外,我这里重点介绍switch分支结构
swich 表达式 {
case 表达式1,表达式2,表达式3:
语句块
fallthrough
default:
语句块
}
表达式可以是变量或函数
case相当于if
当有对个表达式时,是以或连接各个表达式
default先当与else
swtch后面也可以什么都不写
fallthrough是swich穿透,默认穿透一层,相当于满足其条件执行完语句块后还可以执行其他满足条件的语句块。
1. num1 := 10 for i:=0; ifor 后面如果什么也不写,相当于无限循环
12.遍历数组var str [5]int = [5]int{1,2,3,4,5} for index,val := range str{ 语句块 }index相当于下标,val相当于值
13.多层循环break和continue的使用lable1: for i:=1;i<10;i++{ lable2: for j:=1;j<10;j++{ } }break是跳出循环执行循环后面的语句,但是break默认只能跳出一层循环,所以需要在循环前加上lable标签,使用break lable1表示跳出哪个循环
14.goto 基本介绍(不推荐使用)
continue和break一样只能跳出一个循环,不同的是continue是跳出本次循环,继续下一次循环num1 :=1 if num1 == 1{ goto lable1 } fmt.println("你好1") lable1: fmt.println("你好2")输出的会是"你好2"
15.函数定义的基本语法:func 函数名(形参 类型,形参 类型)(返回值 类型){ 执行语句 }16.包的一些知识点go查找路径默认从GOPATH目录下的src下去找
17.打包语法
包的package可以自定义
如果需要函数或变量名让其他包使用,首字母必须大写
使用时先导包 : import 自定义名 "路径"go build -o 指定路径 需要打的包名
18.自定义类型的细节
如果指定路径没有则自创type mytype int自定义类型mytype虽然是int类型但不完全一致
19.func可以当参数传递
他们之间不能进行运算,运算前需要转int类型才可以运算func mytype1(num1 int, num2 int)int{ } func mytype2(n1 func(int,int)int, num1 int, num2 int){ 语句块 } fun main(){ num1 := 1 num2 := 2 mytype2(mytype1,num1,num2) }20.可变参数func args1(args... int){ fmt.Println(args) } func main(){ args1(1,2,3,4) }args是一个切片类型的数据
21.init函数细节当你的包里面定义了一个init函数时,init会在main函数之前被调用
22.匿名函数细节func (n1 int, n2 int)int{ return n1+n2 }(n1,n2) 或 a := func (n1 int, n2 int)int{}(n21,n2)匿名函数会在创建函数之后直接被调用
23.闭包func Addupper()func(int,int)int{ return func(n int,n2 int)int{ return n+n2 } } func main(){ add := Addupper() num3 := add(2,3) fmt.Println(num3) }24.defer延迟机制defer用在函数内部,当函数执行完毕时会自动执行defer后面的语句,一般用于关闭数据库的连接
25.时间日期import "time" now := time.Now() # 获取当前时间 now.Format("2006-0102 15:04:05") #格式化日期时间 now.Unix() #秒数时间戳 now.UnixNano() #纳秒数时间戳26.捕获异常defer+recoverdefer func(){ err := recover() //revcover可以捕获到异常 if err != nil{ fmt.Println("err",err) } }捕获异常的最大作用在于当程序报错时,后面的代码还可以执行
27.自定义异常 errors.New和panic内置函数import "errors" errors.New("代码执行错误") Panic(err)自定义异常的最大作用在于读取文件错误时后面的代码不能执行,需要终止程序
28.数组(值类型)var num [3]int = [3]int{1,2,3} var num = [...]int{8,9,10} var num = [...]int{0:8,1:9,2:10}29.slice切片(值类型)var num [3]int = [3]int{1,2,3} var slice1 := num[:] var slice2 := make([]int,4,10) #4是大小,10是容量 var slice3 []int = []int{1,2,3}注意:切片和数组是有很大区别的,数组的大小是固定的,切片大小可以变化
var slice1 []int = []int{1,2,3} slice1 = append(slice,4) var slice2 = make([]int,1) copy(slice2,slice1) #将slice1的数据copy给slice230.map(引用类型) key-value数据结构var a map[string]string := make(map[string]string) 增 改: a["key"] = value 删: delete(a,"key") 查: val,finRes := a["key"]如果遍历map只能使用for-range遍历
31.结构体type Logins struct { Username string `json:"userename"` Password string `json:"password"` }序列化/反序列化import "encoding/json" var u Logins = Logins{"Username":"123","Password":"123"} 序列化: jsonstr,err := json.Marshal(结构体变量) if err != nil{ fmt.Println("序列化错误") } 反序列化: json.Unmarshal([]byte(jsonstr),&u)



