本文已参与[新人创作礼]活动,一起开启掘金创作之路
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情
基本数据类型
//指定类型
var age int = 77
var price float32 = 0.36789
var price2 float64 = 0.36789
//自动推导类型:=
a := 10
b, c, d := 1, 2, 3 //多变量赋值
o, p, _ := 1, 2, 3 //_代表匿名变量
//占位符
fmt.Printf("%d\n", age) //占位符%d表示输出整型
fmt.Printf("%.3f\n", price) //占位符%f表示输出浮点型,默认保留6位小数,.3代表保留3位小数, 第四位四舍五入
fmt.Printf("%s\n", str) //占位符%s表示输出字符串
//常量
const NAME = 12
//枚举
const (
aa = iota
bb = iota
cc = iota
)
//枚举简写
const (
aaa = iota
bbb
ccc
)
类型转换
Golang各种数值占据的大小
int类型的大小为 8 字节 int8类型大小为1 字节 int16类型大小为 2 字节 int32类型大小为 4 字节 int64类型大小为 8 字节
数据类型占据的范围
int8: -128 ~ 127 int16: -32768 ~ 32767 int32: -2147483648 ~ 2147483647 int64: -9223372036854775808 ~ 9223372036854775807 uint8: 0 ~ 255 uint16: 0 ~ 65535 uint32: 0 ~ 4294967295 uint64: 0 ~ 18446744073709551615
//string转int
strconv.Atoi
strconv.ParseInt
strconv.ParseUint
//int转string
strconv.Itoa
strconv.FormatInt
strconv.FormatUint
//string转float
strconv.ParseFloat
//float转string
strconv.FormatFloat
int到float或者float到int 直接使用float(i) 或者 int(f) 直接进行转换即可
条件语句
//条件语句
var index = 0
switch index {
case 1:
break
case 2:
break
default:
break
}
// 循环,...代表不定参
func test(a int, b ...string) (string, int) {
for i := 0; i < 20; i++ {
if i > 10 {
break
}
fmt.Println(i)
}
//加强for循环
for i, data := range b {
fmt.Println("下标", i)
fmt.Println("数据", data)
}
//不使用的变量可以用匿名变量(_)接收
for _, data := range b {
fmt.Println("数据", data)
}
return "我的", 999
}
函数
//函数首字母大写可以被其他包使用,小写本包使用
func sums() {
dosum(1,2,3,4,5)
}
//函数参数为不定参,传递方式为c[0:]...
func dosum(c ...int) {
sum("aaa", c[0:]...) //从0开始
sum("aaa", c[2:]...) //从2开始
sum("aaa", c[:2]...) //从0到2,不包含2
sum("aaa", c[1:3]...) //从1到3,不包含3
}
//不定参入参,多个返回类型
func sum(str string, arg ...int, ) (int, string, string, int) {
b := arg[0]
return b+45,"我",str,66
}
自定义函数类型
//自定义函数类型(类似string,int,float),函数类型其实就是一个指针
type countString func(string, int) (int, string,int)
func tocount(s string,i int)(int, string,int) {
return 1,"5斤",78
}
func ccs(str countString) {
}
//定义并使用
var cs countString
cs = tocount
cs("牛肉",89)
ccs(cs)
匿名函数
//匿名函数
func sums() {
//在函数内部定义一个匿名函数,函数后面跟(),代表调用
func(a int, b int) {
h := a + b
fmt.Println(h)
}(1, 2)
//方式二
f := func(a int, b int) {
h := a + b
fmt.Println(h)
}
f(1, 2)
}
递归函数
//递归函数
func counts(a int) {
if a == 1 {
return
}
fmt.Println("当前值", a)
counts(a - 1)
}
多目录编程
开发工具:GoLand (www.jetbrains.com/go/) 同级别目录多go文件编程, golang edit confingration 设置runkind 为directory 和设置directory 路径为当前go文件所在目录
不同级别目录多文件编程, 需要用包名.函数执行
数组
//声明数组方式一
var ages [10]int
ages[0] = 11
//声明数组方式二
var names = [10]int{2, 3}
//修改元素
names[5] = 22
//二维数组方式一
var list [3][5]int
list[0][0] = 12
list[0][1] = 13
list[1][1] = 13
//二维数组方式二
var list2 = [3][5]int{{1, 2}, {3, 4}}
切片(自动扩容的数组)
//切片(动态数组),建议用切片代替普通数组
var names2 = []int{2, 3, 5, 67, 78}
var names3 = []int{1: 20, 5: 30} //下标:元素
var names4 = [...]int{1: 20, 5: 30} //下标:元素
//二维切片(动态数组),建议用切片代替普通数组
var list3 = [][]int{{1, 2, 6, 7, 8, 9}, {3, 4}}
var list4 = [][]int{1: {1, 2, 6, 7, 8, 9}, 5: {3, 4}} //下标:元素
var list5 = [][]int{1: {1: 1, 3: 2, 6,}, 5: {3, 4}} //下标:元素
//长度
lens := len(names2)
//容量
caps := cap(names2)
//赋值不能超过当前切片范围,不然下标越界
//names2[10] = 2
//往切片中添加数据,append时,如果超出容量会自动扩容,为上一次容量*2,超过1024字节,则每次扩容1/4
ints := append(names2, 5)
//截取切片(从1到3,不包含下标3)
ints2 := names2[1:3]
fmt.Println("截取", ints2)
//拷贝切片
var cname = make([]int, 4)
var length = copy(cname, names2) //开辟独立空间,修改copy后的数据不影响原数据
字符串常用方法
var a = "积极,你好,你真好"
var c = " 积 极,你好, 你真 好 "
var d = "===积=== 极===你好, 你真好==="
var b = "你"
var result = strings.Contains(a, b) //a包含b
var stringlist = []string{"138", "8765", "9865"}
var sresult = strings.Join(stringlist, "-")
var index = strings.Index(a, b) //b在a第一次出现的下标6的位置,中文一个文字3个index
var rstr = strings.Repeat(b, 10) //将字符串重复10次
var rep = strings.Replace(a, "你", "you", 2) //2代表只替换2次,<0 代表全部替换
var rep2 = strings.ReplaceAll(a, "你", "you")
//根据逗号截取
var sp = strings.Split(a, ",")
//去除字符串首尾指定内容
var tri = strings.Trim(c, " ")
var tris = strings.Trim(d, "=")
//去除首尾空格
strings.Fields(" ")
字符串类型转换
str := "hello would"
//字符串转为字符切片
ss := []byte(str) //强制类型转换
//字符切片转为字符串
newstr := string(ss)
fmt.Println("字符切片", ss)
fmt.Println("切片转为字符串", newstr)
for i := 0; i < len(ss); i++ {
fmt.Printf("%c", ss[i])
}
//字符串转换
bstr := strconv.FormatBool(true)
boo, err := strconv.ParseBool("false")
inttostr := strconv.Itoa(123)
strtoint, err := strconv.Atoi("345")
strconv.ParseInt("12345", 10, 64)
strconv.ParseFloat("4.123", 64)
//其他类型转成切片
slice := make([]byte, 0, 1024)
slice = strconv.AppendBool(slice, true)
slice = strconv.AppendInt(slice, 234, 10)
fmt.Println("转成切片:", string(slice))
if err != nil {
fmt.Println("转换出错")
} else {
fmt.Println(boo)
fmt.Println(inttostr)
fmt.Println(strtoint)
}
map
//方式一
var mymap map[int]string = map[int]string{12: "张飞", 22: "诸葛亮", 2: "刘备"}
mymap[12] = "飞飞"
fmt.Println("map", mymap)
for k, v := range mymap {
fmt.Println(k)
fmt.Println(v)
fmt.Println(mymap[k])
}
//方式二
//map的长度是自动扩容的
newmap := make(map[string]string)
newmap["1"] = "菲菲"
newmap["11"] = "看看"
fmt.Println(newmap)
//map中保存数组
strs := []string{"飞机", "火车"}
strs2 := []string{"轮船", "看看"}
mm := make(map[int][]string)
mm[0] = strs
mm[22] = strs2
fmt.Println(mm)
//根据key删除元素
delete(mm, 22)
//可以用作判断是否存在某个key 的值
value, ok := mm[888]
if ok {
fmt.Println(value)
} else {
fmt.Println("未找到数据")
}
结构体
//结构体
type User struct {
id int
name string
age int
}
func main() {
uu := User{2, "诸葛亮", 35}
var u2 = User{id: 3, name: "刘备", age: 56}
var user User
user.name = "张飞"
user.age = 56
user.id = 1
fmt.Println(uu)
fmt.Println(u2)
fmt.Println(user)
//结构体名默认指向第一个成员地址
fmt.Printf("%p\n", &uu)
fmt.Printf("%p\n", &uu.id)
fmt.Printf("%p\n", &uu.name)
if uu == u2 {
//比较两个结构体所有成员值是否相同
}
//结构体数组
var suts1 = [2]User{
{1, "张飞", 32}, {3, "方法", 32},
}
//结构体切片
var suts2 = []User{
{1, "张飞", 32}, {3, "方法", 32},
}
//往切片中添加结构体
stu3 := append(suts2, User{3, "11", 33})
fmt.Println(suts1)
fmt.Println(suts2)
fmt.Println(stu3)
//结构体放在map中使用
m := make(map[int]User)
m2 := make(map[int][]User)
m[0] = User{1, "ff", 33}
m[1] = User{2, "统一", 2}
m2[0] = []User{{3, "gg", 2}, {4, "ww", 56}}
m3 := append(m2[0], User{6, "hj", 67})
delete(m, 0)
fmt.Println(m)
fmt.Println(m2)
fmt.Println(m3)
getstumap(m)
//数组入参
func getstumap(user map[int]User) {
//指针不能直接使用这样修改
//user[0].name = "典韦"
//先定义临时变量赋值后修改
newUser := user[0]
newUser.name = "赵云"
user[0] = newUser
fmt.Println("修改", user)
}
//切片入参
func getstumaps(user map[int][]User) {
}
指针
指针变量
var a = 39
//p获取了a的地址
var p *int = &a
fmt.Println(p)
fmt.Printf("%p\n", p)
fmt.Printf("%T\n", p)
//通过指针间接修改变量的值,指针类型存储的都是无符号16进制整型数据
*p = 55
fmt.Println(a)
fmt.Println(*p)
//开辟内存空间,返回数据类型指针,go语言也有GC
var s *int = nil
s = new(int)
*s = 66
fmt.Println(s)
fmt.Println(*s)
//指针作为函数参数
aa := 1
bb := 2
swap(&aa, &bb)
fmt.Println(aa, bb)
func swap(a *int, b *int) {
*a = 22
*b = 33
temp := *a
*a = *b
*b = temp
}
数组指针
//数组指针
var pp *[3]int
ps := [3]int{1, 2, 3}
pp = &ps
pps := &ps
//通过指针间接操作数组
fmt.Println(*pp)
fmt.Println(*pps)
//通过指针修改的2种方式
(*pps)[0] = 55
//仅限数组,切片不可这样使用
pp[0] = 34
var p1 = &ps
var p2 = &ps[0]
fmt.Printf("%T\n", *p1)
fmt.Printf("%T\n", *p2)
//存储数组指针的数组
b1 := [2]int{1, 2}
b2 := [2]int{5, 6}
var aar = [2]*[2]int{&b1, &b2}
fmt.Println(aar)
fmt.Println(*aar[0])
var e *[2]int
//创建内存空间存储e
e = new([2]int)
e[0] = 1
e[1] = 5
fmt.Println(e)
//数组指针作为参数
func add(p *[2]int) {
}
切片指针
//切片指针
a1 := 1
a2 := 2
var gets = []*int{&a1, &a2}
*(gets[0]) = 200
fmt.Println(gets)
fmt.Println(a1)
k := []int{1, 2, 3}
ks := &k
//这种写法错误,切片不可以这样用
//ks[0] = 24
//这种是可以的
(*ks)[0] = 35
//切片指针作为参数
func add2(p *[]int) {
*p = append(*p, 1, 2)
}
结构体指针
//结构体指针
var uus = &user
fmt.Printf("%T\n", uus)
fmt.Println("结构体指针", *uus)
//通过指针间接修改结构体数据
(*uus).name = "菲菲"
//指针也可直接操作
uus.name = "飞飞"
fmt.Println("结构体指针2", *uus)
//使用map存储结构体指针
//m11 :=make(map[int]*User)
//m22 :=make(map[int]*[2]User)
//m33 :=make(map[int]*[]User)
//结构体指针作为参数
func add3(us *User) {
}
多级指针
//多级指针
var hk = 1
var hk1 = &hk
var hk2 = &hk1
var hk3 = &hk2
*hk1 = 33
**hk2 = 44
***hk3 = 55
fmt.Println(*hk1)
fmt.Println(**hk2)
fmt.Println(***hk3)
fmt.Println(hk)