go初识
- 定义变量
第一种:var 变量名 数据类型
变量名=赋值
var 变量名 数据类型=赋值
第二种:var 变量名=赋值
第三种:变量名:=赋值
- 数据类型
bool int8 int16 int32 int64 uint byte float32 float64 complex string
array slice map struct interface channel。。。
- 操作符
&:都为1,才为1,有一个0,就为0
|:都为0,才为0,有一个1,就为1
异或:^
a^b:对应位值不同为1,相同为0
^a:按位取反:1-->0 0-->1
位清空:&^
a&^b:对于b上的每一个数值,如果为0,则取a对应位上的数值,如果为1,则就取0
- 格式化打印
%v原样输出,%T打印类型,%tbool类型,%s字符串,%f浮点,%d10进制整数,%b二进制整数,%o8进制,%x/%X16进制,%x:0~9,a~f,%X:0~9,A~F,%c字符,%p地址。。。
- switch:
fallthrough:当case匹配成功后,执行该语句,遇到fallthrough,后面紧邻的case无需匹配,执行
break:强制提前结束
- for
break:彻底结束这层循环
continue:结束了某一次循环,下次继续
- goto
- 随机数
设置种子:rand.Seed(time.Now.UnixNano())
生成:rand.Intn(范围)
- 长度和容量
len(array/map/slice/string)实际存储
map()最大容量
- 遍历数组
package main
import "fmt"
func main() {
a := [...][2]int{{12, 23}, {2, 3}, {1, 5}}
for _, arr := range a {
for _, val := range arr {
fmt.Print(val, "\t")
}
fmt.Println()
}
}
- 切片slice
指向一个底层数组,向切片中添加数据时,如果没超过容量,直接添加,如果超过容量,自动成倍扩容,一旦扩容,重新指向一个新的底层数组,引用类型,浅拷贝
var s1 []int
s2:=[]int{1,2,3,4}
s3:=make([]int,0,5)
s3=append(s3,1,2,3,4,5,5)
s3=append(s3,s2...)
在已有数组中,直接创建切片:
package main
import "fmt"
func main() {
a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
s1 := a[:5]
s2 := a[3:8]
s3 := a[:]
fmt.Printf("%T...%v\n", s1, s1)
fmt.Printf("%T...%v\n", s2, s2)
fmt.Printf("%T...%v\n", s3, s3)
}
- map
key不能重复,如果重复,新的value会覆盖原来的,程序不会报错
打印时,如果key存在,获取数值,如果key不存在,获取value类型的零值
创建:
var map1 map[int]string//没有初始化,nil,无法直接使用
var map2 = make(map[int]string)//创建
map2[1]="C"//添加
var map3 = map[string]int{"go":98,"python":87,"java":79}
获取:
可以通过value,ok :=map3["Go"]判断切片中有无对应的值,如果没有,ok为false,反之
删除:
delete(map,key)
如果key存在,直接删除
如果key不存在,删除失败
遍历:
for key,value:=range map3{
fmt.Println(key,value)
}
- strings包下函数
strings.Contains(字符串,查找的字符串)(bool):是否包含指定的内容
strings.ContainsAny(字符串,查找的字符串)(bool):是否包含其中任意一个字符
strings.Count(字符串,查找的字符串)(int):统计出现次数
strings.Index(字符串,查找字符串)(int):查找字符串位置,如果不存在返回-1
strings.Join
strings.Split
strings.Repeat
strings.Replace
- strconv包
- 可变参数
函数的参数的类型确定,但个数不确定
参数名...参数类型,相当于切片
- defer
多个defer函数:先延迟的后执行,后延迟的先执行
注意点:略
- 函数
可以看做一种特殊变量,比如:func(int,int)
函数名():将函数进行调用
函数名:指向函数体的内存地址
匿名函数:
func (){
.....
}()
fun1:=func(a,b int)int{
return a+b
}
rest:=func (a,b int)int{
return a+b
}(10,20)
- 高阶函数
接收了一个函数作为参数的函数
- 闭包
将匿名函数作为另一个函数的返回值,形成闭包结构
一个外层函数中,有内层函数,该内层函数中,会操作外层函数的局部变量(外层函数中的参数,或者外层函数中直接定义的变量)
局部变量的生命周期会发生改变,正常的局部变量随着函数调用而创建,随着函数的结束而摧毁
但是闭包结构中的外层函数的局部变量并不会随着外层函数的结束而摧毁,因为内层函数还要继续使用
package main
import "fmt"
func main() {
res1 := increment()
fmt.Printf("%T\n", res1)
fmt.Println(res1)
v1 := res1()
fmt.Println(v1)
v2 := res1()
fmt.Println(v2)
}
func increment() func() int { //外层函数
i := 0 //局部变量
fun := func() int { //内层函数
i++
return i
}
return fun
}
func() int
0x8f52e0
1
2
- 回调函数
作为另一个函数的参数的函数
package main
import "fmt"
func main() {
res := oper(100, 8, func(a, b int) int {
if b == 0 {
fmt.Println("除数不能为0")
return 0
}
return a / b
})
fmt.Println(res)
}
func oper(a, b int, fun func(int, int) int) int {
fmt.Println(a, b, fun)
res := fun(a, b)
return res
}
100 8 0x463260
12
- 数组指针
是一个指针,存储数组的地址
var p1 *[4]int
- 指针数组
是一个数组,存储的数据类型是指针
var p2 [4]*int
- 函数指针
一个指向函数的指针
- 指针函数
一个函数,该函数返回值是一个指针
- 结构体
type Person struct{
.......
}
定义:
var p1 Person
p1.name="..."
p2:=Person{}
p3:=Person{name:"...",age:18,...}
语法:
type 变量名 struct{
...
}
- 结构体嵌套
1.模拟继承性:
type A struct{
.....
}
type B struct{
A//匿名字段
}
2.模拟聚合关系:
type C struct{
....
}
type D struct{
c C
}
- new
new返回指针
var pp1 *Person
pp1=&p1
pp2:=new(Person)
- 方法method
包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或一个指针
与函数类似,区别需要有接受者
语法:
func (接受者) 发法名(参数列表)(返回值){
}
子类对象可以访问父类方法
- 接口interface
当某个类型为这个接口中的所有方法提供了方法的实现,它呗称为实现接口
接口和类型的实现关系,非嵌入式的
当使用接口类型对象时,可以使用任意实现类对象代替
接口对象不能访问实现类中的属性
一个函数如果接受接口类型作为参数,实际上可以传入该接口的任意实现类型对象作为参数
定义一个类型为接口类型,实际上可以赋值为任意实现类对象
空接口:
type 名 interface{
}
不包含任何方法,所有类型都实现空接口,可以付任何数值
map:key字符串,value任意类型
map1:=make(map[string]interface{})
slice:存储任意类型
slice1:=make([]interface{},0,10)
slice1=append(slice1,1,2,3,"abc")
接口断言
os包