GoLang语言学习记录(一)


createdtime 20210827

updatedtime 20210827

author venki.chen


摘要

以学习基础知识为主(数据类型、控制结构以及注意事项)……

数据类型

  1. 定义结构体
package api

import (
	"fmt"
)

// Teacher 定义结构体
type Teacher struct {
	Name   string
	Age    int
	School string
}

// AccessApiOne 入口
func AccessApiOne() {
	// 创建结构体方式1
	var t1 Teacher
	t1.Name = "venki.chen"
	t1.Age = 28
	t1.School = "广西科技大学"
	fmt.Println(t1)
	fmt.Println("----------------------")

	// 创建结构体方式2
	var t2 Teacher = Teacher{}
	t2.Name = "cwxc"
	t2.Age = 28
	t2.School = "广西科技大学"
	fmt.Println(t2)
	fmt.Println("--------------------------")

	// 创建结构体方式3 返回结构体指针
	var t3 *Teacher = new(Teacher)
	/*(*t3).Name = "slp"
	(*t3).Age = 26
	(*t3).School = "福建师范大学"*/
	/*之所以(*t3).Name 和t3.Name可以互用是因为go底层对此种定义进行了取值运算,会将t3.Name转换为(*t3).Name*/
	t3.Name = "slp"
	t3.Age = 18
	t3.School = "福建师范大学"
	fmt.Println(*t3)
	fmt.Println("--------------------------")

	// 创建结构体方式4 返回结构体指针
	var t4 *Teacher = &Teacher{}
	/*(*t4).Name = "slp"
	(*t4).Age = 26
	(*t4).School = "福建师范大学"*/
	/*之所以(*t4).Name 和t4.Name可以互用是因为go底层对此种定义进行了取值运算,会将t4.Name转换为(*t4).Name*/
	t4.Name = "slp"
	t4.Age = 26
	t4.School = "福建师范大学"
	fmt.Println(*t4)
	fmt.Println("--------------------------")
}
  1. 定义map
func MapMain() {
	// 定义map 方式一
	var a map[int]string = make(map[int]string)
	a[2021082601] = "陈"
	a[2021082602] = "文"
	a[2021082603] = "小"
	a[2021082604] = "超"
	a[2021082605] = "石"
	a[2021082606] = "丽"
	a[2021082606] = "胜"
	a[2021082607] = "平"
	fmt.Println(a)
	fmt.Println("-----------------")
	
	// 定义map 方式二
	b := make(map[int]string)
	b[2021] = "1"
	b[2022] = "2"
	fmt.Println(b)
	fmt.Println("-----------")
	
	// 定义map 方式三
	c := map[int]string{
		202106: "小",
		202107: "超",
	}
	fmt.Println(c)
	fmt.Println("--------")
	map1 := make(map[string]map[int]string)
	// 赋值
	map1["班级1"] = make(map[int]string)
	map1["班级1"][2021082601] = "陈陈1"
	map1["班级1"][2021082602] = "文文1"
	map1["班级1"][2021082603] = "小小1"
	map1["班级1"][2021082604] = "超超1"

	map1["班级2"] = make(map[int]string)
	map1["班级2"][2021082601] = "陈陈2"
	map1["班级2"][2021082602] = "文文2"
	map1["班级2"][2021082603] = "小小2"
	map1["班级2"][2021082604] = "超超2"
	for k1, v1 := range map1 {
		for k2, v2 := range v1 {
			fmt.Printf("总共班级数为:%v,班级为:%v,共有学生:%v个,分别是:姓名为:%v,
			学号为:%v的学生\n", len(map1), k1, len(v1), v2, k2)
		}
	}

	fmt.Println("--------------")
	accountedInvoiceAfId := make([]int, 0)
	fmt.Printf("切片的长度为:%v,容量为:%v\n", len(accountedInvoiceAfId), 
	cap(accountedInvoiceAfId))
}
  1. 定义切片
func sliceMain() {
	// 数组
	var intarr [6]int = [6]int{3, 6, 9, 1, 4, 7}
	fmt.Println(intarr)

	// 切片
	slice := intarr[1:3]
	fmt.Println(slice)
	fmt.Printf("slice的元素个数:%v\n", len(slice))
	fmt.Printf("slice的容量是:%v\n", cap(slice))
	fmt.Println("----------")
	fmt.Printf("数组中下标为1的元素的地址是:%p\n", &intarr[1])
	fmt.Printf("切片中下标为0的元素的地址是:%p\n", &slice[0])
	fmt.Println("----------")
	slice[0] = 16
	fmt.Println(intarr)
	fmt.Println(slice)
	fmt.Println("----------")

	// 创建切片
	slice1 := make([]int, 4, 20)
	fmt.Println(slice1)
	fmt.Printf("切片的长度是:%v\n", len(slice1))
	fmt.Printf("切片的容量是:%v\n", cap(slice1))
	fmt.Println("----------")

	// 遍历切片
	var arr3 [6]int = [6]int{1, 2, 3, 4, 5, 6}
	slice2 := arr3[0:6]

	// 遍历方式1
	for i := 0; i < len(slice2); i++ {
		fmt.Printf("切片的第%v个值是:%v\n", i+1, slice2[i])
	}

	fmt.Println("--------------")
	
	// 遍历方式2
	for key, value := range slice2 {
		fmt.Printf("slice2[%v]=%v\n", key, value)
	}
	fmt.Println(slice2)
	slice2 = append(slice2, 88, 50)

	fmt.Println(slice2)
}
  1. 定义数组
func arrMain() {
	var arr [2][3]int16

	fmt.Println(arr)
	fmt.Println("---------------------------")

	// 数组内存地址
	fmt.Printf("arr的内存地址是:%p\n", &arr)
	fmt.Printf("arr[0]的内存地址是:%p\n", &arr[0])
	fmt.Printf("arr[0][0]的内存地址是:%p\n", &arr[0][0])
	fmt.Println("---------------------------")

	// 初始化数组
	var arr1 [2][3]int = [2][3]int{
   
   {1, 2, 3}, {4, 5, 6}}
	fmt.Println(arr1)
	fmt.Println("---------------------------")

	// 变量数组
	var arr2 [3][3]int = [3][3]int{
   
   {1, 2, 3}, {4, 5, 6}, {7, 8, 9}}

	// 方式1遍历
	for i := 0; i < len(arr2); i++ {
		for j := 0; j < len(arr2[i]); j++ {
			fmt.Printf("二维数组第%v层第%v列元素是:%v\n", i+1, j+1, arr2[i][j])
		}
	}
	fmt.Println("---------------------------")

	// 方式2编列
	for key, value := range arr2 {
		for k, v := range value {
			fmt.Printf("二维数组第%v层第%v列元素是:%v\n", key+1, k+1, v)
		}
	}
}
  1. 基本数据类型
func main() {
	// 字符串数据类型
	var s1 string = "你好全面拥抱Golang"
	fmt.Println(s1)
	var s2 string = "abc"
	s2 = "def"
	fmt.Println(s2)
	var s3 string = "abcdef\\ghijklm"
	fmt.Println(s3)
	var s4 string = "abcdef" + "ghijklm"
	fmt.Println(s4)
	var s5 string = `if else elseif`
	fmt.Println(s5)

	// 基本数据类型默认值
	var a int
	var b float32
	var c float64
	var d bool
	var e string
	fmt.Println(a)
	fmt.Println(b)
	fmt.Println(c)
	fmt.Println(d)
	fmt.Println(e)

	// 数据类型显式转换
	var n1 int = 100
	var n2 float32 = float32(n1)// n1的类型不变
	fmt.Println(n1)
	fmt.Println(n2)
	fmt.Printf("%T",n1)
	fmt.Println()
	fmt.Printf("%T",n2)
	fmt.Println()
	var n3 int64 = 888888
	var n4 int8 = int8(n3)
	fmt.Println(n4)
	var venkiChen string = "venki.chen"
	fmt.Println(venkiChen)
}

控制结构

  1. for循环
func forModule() {
	var i1 int = 1
	var i2 int = 2
	var i3 int = 3
	var i4 int = 4
	var i5 int = 5
	var sum int = 0
	sum += i1
	sum += i2
	sum += i3
	sum += i4
	sum += i5
	fmt.Printf("求和之后:%v\n", sum)

	var sum int = 0
	var i int = 1
	i++
	sum += i
	sum += i
	sum += i
	sum += i
	sum += i
	fmt.Printf("求和之后:%v,%i", sum, i)
	var sum int = 0
	for i := 1; i <= 5; i++ {
		sum += i
	}
	fmt.Printf("%v", sum)

	for {
		fmt.Println("你好venki.chen")
	}
}
  1. switch分支
func branchModuleToSwitch() {
	var count int
	fmt.Println("请输入您的成绩:")
	fmt.Scanln(&count)
	num := count / 10
	switch num {
	case 10, 11, 12:
		fmt.Printf("你的成绩是:%v,被评为A级\n", count)
	case 9:
		fmt.Printf("你的成绩是:%v,被评为B级\n", count)
		fallthrough
	case 8:
		fmt.Printf("你的成绩是:%v,被评为C级\n", count)
	case 7:
		fmt.Printf("你的成绩是:%v,被评为D级\n", count)
	case 6:
		fmt.Printf("你的成绩是:%v,被评为E级\n", count)
	case 5:
		fmt.Printf("你的成绩是:%v,被评为F级\n", count)
	case 4:
		fmt.Printf("你的成绩是:%v,被评为G级\n", count)
	case 3:
		fmt.Printf("你的成绩是:%v,被评为H级\n", count)
	case 2:
		fmt.Printf("你的成绩是:%v,被评为I级\n", count)
	case 1:
		fmt.Printf("你的成绩是:%v,被评为J级\n", count)
	case 0:
		fmt.Printf("你的成绩是:%v,被评为K级\n", count)
	default:
		fmt.Printf("你的成绩是:%v,被评为L级\n", count)
	}
}
  1. if分支
func branchModuleToIf() {
	var count int
	fmt.Println("请输入您要填写的数据:")
	fmt.Scanln(&count)
	if count < 30 {
		fmt.Printf("你输入的数为:%v小于30\n", count)
	} else {
		fmt.Printf("你输入的数为:%v大于30\n", count)
	}

	if count >= 90 {
		fmt.Printf("你的成绩为:%v,为A级别\n", count)
	}
	if count >= 80 && count < 90 {
		fmt.Printf("你的成绩为:%v,为B级别\n", count)
	}
	if count >= 70 && count < 80 {
		fmt.Printf("你的成绩为:%v,为C级别\n", count)
	}
	if count >= 60 && count < 70 {
		fmt.Printf("你的成绩为:%v,为D级别\n", count)
	} else {
		fmt.Printf("你的成绩为:%v,为E级别\n", count)
	}

	if count >= 90 {
		fmt.Printf("你的成绩为:%v,为A级别\n", count)
	} else if count >= 80 {
		fmt.Printf("你的成绩为:%v,为B级别\n", count)
	} else if count >= 70 {
		fmt.Printf("你的成绩为:%v,为C级别\n", count)
	} else if count >= 60 {
		fmt.Printf("你的成绩为:%v,为D级别\n", count)
	} else {
		fmt.Printf("你的成绩为:%v,为E级别\n", count)
	}

	if count > 10 {
		fmt.Println("a")
	} else if count > 5 {
		fmt.Println("b")
	}
}

注意事项

  1. ++ --只能单独使用,不参与到运算中去;
  2. Switch分支不能用var声明变量,只能用:=;声明;
  3. go语言不支持函数重载(函数名相同形参不同);
  4. 自定义数据类型,其实就是给数据类型起个别名(但是在赋值时必须数据类型也一样);
  5. main函数必须在main包中;
  6. 同一个包中不同的文件也不能声明重名函数;
  7. 同一包下面不同的文件声明报名可以不和文件夹名字一致,但是包文件中声明包文件包名必须一致;
  8. 执行顺序:(导入包中的init函数先被执行)> 全局变量 > init函数 > 大于main函数;
  9. 闭包:因为闭包可以保留上一次引用的某个值,传入一次就可以反复使用;
// GetSum 定义一个函数,返回值类型为函数并且这个函数的形参为整型,返回值为整型
func GetSum() func(int) int {
	var sum int = 0
	return func(num int) int {
		sum += num

		return sum
	}
}
  1. defer关键字:遇到defer关键字,会将后面的代码语句压入栈中,也会将相关的值同时拷贝入栈中,不会随着函数后面的变化而变化,应用场景:比如你想关闭某个使用的资源,在使用的时候直接随手defer,因为defer有延迟机制(函数执行完毕再执行defer压入栈的语句),所以你用完随手写了关闭比较省心省事;
Add(30,60)
func Add(num int, num1 int) int {
	// 在Golang中,程序遇到defer关键字,不会立即执行defer后的语句,而是将defer后的语句压入一个栈中,然后继续执行函数后面的代码
	defer fmt.Println("num=", num)
	defer fmt.Println("num1=", num1)
	// 栈的特点先进后出
	// 在函数执行完成后,从栈中取出语句开始执行,按照先进后出的规则执行语句
	var sum int = num + num1
	fmt.Println("sum=", sum)

	return sum
}
  1. 切片定义后不可直接使用(是一个空[]),需要让其引用一个数组或者用make初始化切片,切片不能越界;
  2. map如果只是声明并没有赋值,那么是不会分配内存空间的,arr则不然;map的key和value是无序的;key是不可以重复的,如果重复后一个value会替换前一个value;make初始化map时,第二个参数可以省略,默认分配一个大小;
  3. 初始化结构体时,如果属性包含指针,切片以及映射时,没有进行make那么并没有分配空间,没有分配空间,赋值就会报错,所以必须初始化的同时进行make;
  4. 结构体时值类型,不同的结构体之间相互独立,不受影响;

猜你喜欢

转载自blog.csdn.net/qq_38721452/article/details/119949345