Go基础部分总结1

使用总结

1.go自动识别变量类型
输入:

	name := "xx"
	fmt.Println(name)

输出:

xx

2.Printf使用
(1)输入:

func main() {
	name := "xx"
	age := 10
	fmt.Println(name, age)
	//Printf 按照指定格式输出
	fmt.Printf("%T,%T", name, age)
}

输出:

xx 10
string,int

(2)输入:

func main() {
	age := 10
	//& 取地址符
	fmt.Printf("数字为:%d,地址为:%p", age, &age)
}

输出:

数字为:10,地址为:0xc000112068

(3)输入:

func main() {
	age := 10
	fmt.Printf("数字为:%d,地址为:%p", age, &age)
	//变量内容发生变化,内存地址不变
	age = 18
	fmt.Println()
	fmt.Printf("数字为:%d,地址为:%p", age, &age)
}

输出:

数字为:10,地址为:0xc00000a0a8
数字为:18,地址为:0xc00000a0a8

转载https://www.cnblogs.com/thsrite/p/11765201.html
在这里插入图片描述
在这里插入图片描述
3.变量值交换
(1)输入

func main() {
	var a int = 1
	var b int = 2
	fmt.Println(a, b)
	//GO实现数值交换
	a, b = b, a
	fmt.Println(a, b)
}

输出

1 2
2 1

4.匿名变量
(1)Go函数使用
输入:

// Go中函数的定义
func test() (int, int) {
	return 100, 200
}

func main() {
	//函数调用
	a, b := test()
	fmt.Println(a, b)
}

输出:

100 200

(2)匿名变量
好处:不占用内存空间
输入:

func test() (int, int) {
	return 100, 200
}

func main() {
	//函数传过来两个值,只使用第一个值,第二个用‘下划线’ _ 进行匿名代替
	a, _ := test()
	fmt.Println(a)
}

输出:

100

5.全局变量与局部变量
定义全局变量,不能使用 name := “ckm” 这种便捷写法
在全局变量中进行变量定义后,依然可以在局部及进行变量定义
输入:

// 定义全局变量
var name = "cc"

func test() {
	fmt.Println(name)
}

func main() {
	test()
	//name = "xx"   //直接对全局变量那么进行赋值
	var name = "XX"  //对name进行重新定义不会报错
	fmt.Println(name)
}

输出:

cc
XX

6.常量定义
(1)常量定义
输入:

func main() {
	//显式定义
	const name1 string = "cc"
	//隐式定义
	const name2 = "kk"
	//定义多个常量
	const num, addr, isTrue = 3.1415, "中国", true

	fmt.Println(name1)
	fmt.Println(name2)
	fmt.Println(num, addr, isTrue)
}

输出:

cc
kk
3.1415 中国 true

(2)递增常量iota
在const关键字出现时,重置为0
常量计数器

func main() {
	//iota
	const (
		a = iota
		b
		c
		d = "hello"
		e
		f = 100
		g
		h = false
		i
		j = iota
		k
	)
	const (
		//重新定义,重新计数
		m = iota
		n
	)

	fmt.Println(a, b, c, d, e, f, g, h, i, j, k, m, n)
}

输出:

0 1 2 hello hello 100 100 false false 9 10 0 1

7.数据类型:布尔(bool)
默认值为false
输入:

func main() {
	var isFlag, isTrue, isOK bool
	isFlag = true
	fmt.Printf("数据类型为:%T,isFlag:%t\n", isFlag, isFlag)
	fmt.Printf("数据类型为:%T,isFlag:%t\n", isTrue, isTrue)
	fmt.Printf("数据类型为:%T,isFlag:%t\n", isOK, isOK)
}

输出

数据类型为:bool,isFlag:true
数据类型为:bool,isFlag:false
数据类型为:bool,isFlag:false

8.数据类型 数字
int、float64类型值默认为0

输入:

func main() {
	var num1 int = 100
	var num2 float64 = 3.1415
	fmt.Printf("数据类型为:%T,num1的值为:%d\n", num1, num1)
	fmt.Printf("数据类型为:%T,num2的值为:%f\n", num2, num2)
	fmt.Printf("数据类型为:%T,num2保留一位小数点:%.1f\n", num2, num2)
}

输出:

数据类型为:int,num1的值为:100
数据类型为:float64,num2的值为:3.141500
数据类型为:float64,num2保留一位小数点:3.1

int 等同于 int64
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

9.字符类型
输入:

func main() {
	var name string
	fmt.Printf("数据类型为:%T,name的值为:%s\n", name, name)

	var str1 = 'A'
	var str2 = "A"
	//ascii码
	fmt.Printf("数据类型为:%T,str1的值为:%d\n", str1, str1)
	fmt.Printf("数据类型为:%T,str2的值为:%s\n", str2, str2)
}

输出:

数据类型为:string,name的值为:
数据类型为:int32,str1的值为:65
数据类型为:string,str2的值为:A

10.字符转换
Go语言不存在隐式类型转换,所有类型转换都必须是显式的
输入:

func main() {
	a := 10
	b := 10.1
	c := float64(a)
	d := int(b)
	fmt.Printf("数据类型为:%T\n", a)
	fmt.Printf("数据类型为:%T\n", b)
	fmt.Printf("数据类型为:%T\n", c)
	fmt.Printf("数据类型为:%T\n", d)
}

输出:

数据类型为:int
数据类型为:float64
数据类型为:float64
数据类型为:int

11.关系运算符
错误输入

func main() {
	a := 10
	//直接输出a++是会报错的
	fmt.Println(a++)  
}

输入:

func main() {
	a := 10
	a++
	fmt.Println(a)
}

输出:

11

12.获取键盘输入
输入:

func main() {
	name := "xx"
	fmt.Println(name)                     //输出并换行
	fmt.Printf("格式为:%T,值为%s", name, name) //格式化输出
	fmt.Print(name)                       //输出

	var x int
	var y float64
	fmt.Println("请输入两个数,第一个数为整数,第二个数为小数")
	fmt.Scanln(&x, &y) //阻塞,等待键盘输入
	//若输入的数据类型不正确,返回默认值
	fmt.Println("x的值为", x)
	fmt.Println("y的值为", y)
}

输出:
在这里插入图片描述
13.switch

输入:

func main() {
	var score = 80
	switch score {
	case 90:
		fmt.Println("A")
	case 80, 70:
		fmt.Println("B")
	case 60:
		fmt.Println("C")
	default:
		fmt.Println("不及格")
	}
	//switch 默认的条件为 bool = true
	switch {
	case true:
		fmt.Println("switch 空 默认为true")
	case false:
		fmt.Println("switch 空 默认为false")
	default:
		fmt.Println("其他")
	}
}

输出:

B
switch 空 默认为true

switch中提供fallthrough可以实现穿透(只穿透一层)
输入:

func main() {
	//switch 默认的条件为 bool = true
	switch {
	case true:
		fmt.Println("switch 空 默认为true")
		fallthrough
	case false:
		fmt.Println("switch 空 默认为false")
	default:
		fmt.Println("其他")
	}
}

输出:

switch 空 默认为true
switch 空 默认为false

使用break终止穿透
输入:

func main() {
	//switch 默认的条件为 bool = true
	switch {
	case true:
		fmt.Println("switch 空 默认为true")
		fallthrough
	case false:
		if true {
			break
		}
		fmt.Println("switch 空 默认为false")
	default:
		fmt.Println("其他")
	}
}

输出:

switch 空 默认为true

14.字符串
(1)字符长度
utf-8里面中文是占3个字节的,所以你使用内置len函数获取中文字符串长度不一定正确
输入:

func main() {
	var name = "我是笑xx"
	fmt.Println(name)
	fmt.Println("字符总长度为:", len(name))
	fmt.Printf("第一个字符为:%c", name[0])
}

输出:

我是笑xx
字符总长度为: 11
第一个字符为:æ

(2)字符遍历
字母数字占一个字符,中文占3个字符
name[i]输出中文会乱码
输出v不会乱码
输入:

func main() {
	var name = "aaa我是笑xx"
	for i, v := range name {
		fmt.Print(i)
		fmt.Printf("%c", name[i])
		fmt.Printf("%c\n", v)
	}
}

输出:

0aa
1aa
2aa
3æ我
6æ是
9ç笑
12xx
13xx

15.函数
输入:

func main() {
	fmt.Println(add(1, 1))
}

func add(a, b int) int {
	return a + b
}

输出:

2

练习使用
输入:

/ 交换函数,并输出
func main() {
	name1, name2 := swap("xx", "ck")
	fmt.Println(name1, name2)
}
/*
*
交换函数
*/
func swap(a, b string) (string, string) {
	return b, a
}

/*
*
输出函数
*/
func printInfo(info string) {
	fmt.Println(info)
}

输出:

ck xx

16.数组与切片
(1)数组
输入:

// 数组(值传递)
func main() {
	ary1 := [3]int{1, 2, 3}
	//输出更改函数执行前的数组
	fmt.Println(ary1)
	//执行函数
	update(ary1)
	//输出变换后的函数
	fmt.Println(ary1)
}

// 变更函数
func update(ary2 [3]int) {
	//输出传递的数组(值传递)
	fmt.Println(ary2)
	//进行数组值变更
	ary2[0] = 100
	//输出ary2值变更后的数组
	fmt.Println(ary2)
}

输出:

[1 2 3]
[1 2 3]
[100 2 3]
[1 2 3]

(2)二维数组
输入:

// 二维数组遍历
func main() {

	arr := [2][3]int{{1, 2, 3}, {4, 5, 6}}
	for k, v := range arr {
		for key := range v {
			fmt.Print(arr[k][key], "\t")
		}
		fmt.Println()
	}
}

输出:

1	2	3	
4	5	6

(3)切片
切片的创建方式:
①定义一个切片,该切片引用已经创建好的数组

arr1 := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}//定义数组
arr2 := arr1[1:3] //左闭右开,切片arr2为[2,3]

②通过make内置函数创建切片
内建函数make分配并初始化一个类型为切片、映射、或通道的对象。其第一个实参为类型,而非值。make的返回类型与其参数相同,而非指向它的指针。其具体结果取决于具体的类型:

  • 切片:size指定了其长度。该切片的容量等于其长度。切片支持第二个整数实参可用来指定不同的容量;它必须不小于其长度,因此 make([]int, 0, 10) 会分配一个长度为0,容量为10的切片。
  • 映射:初始分配的创建取决于size,但产生的映射长度为0。size可以省略,这种情况下就会分配一个小的起始大小。
  • 通道:通道的缓存根据指定的缓存容量初始化。若 size为零或被省略,该信道即为无缓存的。
	//定义一个类型为int,长度为4,容量为20的切片
	//原理:make底层创建一个数组,不可见,不可操作
	slice := make([]int, 4, 20)

③直接指定具体数组

	slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	fmt.Println(slice)

在这里插入图片描述

输入:

func main() {
	//arr1为数组,arr2为切片,arr3为切片
	arr1 := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	arr2 := arr1[1:3] //左闭右开,切片arr2为[2,3]
	arr3 := []int{1, 2, 3}
	fmt.Println(arr1)      //输出切片变化前数组的值
	fmt.Println(cap(arr2)) //输出切片容量
	update(arr2)           //切片值发生变化
	fmt.Println(arr1)      //数组的值发生变化!!!
	fmt.Println(arr2)
	fmt.Println(arr3)
}
func update(arr []int) {
	arr[0] = 0
}

输出:

[1 2 3 4 5 6 7 8 9 10]
9
[1 0 3 4 5 6 7 8 9 10]
[0 3]
[1 2 3]

输入:

// 切片(引用传递)
func main() {
	ary1 := []int{1, 2, 3}
	//输出更改函数执行前的切片
	fmt.Println(ary1)
	//执行函数
	update(ary1)
	//输出变换后的切片
	fmt.Println(ary1)
}

// 变更函数
func update(ary2 []int) {
	//输出传递的切片(引用传递,同一个地址)
	fmt.Println(ary2)
	//进行切片值变更
	ary2[0] = 100
	//输出ary2值变更后的切片
	fmt.Println(ary2)
}

输出:

[1 2 3]
[1 2 3]
[100 2 3]
[100 2 3]

PS:
切片简写方式:
对数组进行切片时,从0开始时可以省略,结束为数组的长度时也可以省略
支持对切片继续切片
输入:

func main() {
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	slice1 := arr[:5]
	slice2 := arr[5:]
	slice3 := arr[:]
	slice4 := slice1[:2]
	fmt.Println(slice1)
	fmt.Println(slice2)
	fmt.Println(slice3)
	fmt.Println(slice4)
}

输出:

[1 2 3 4 5]
[6 7 8 9 10]
[1 2 3 4 5 6 7 8 9 10]
[1 2]

append内置函数
内建函数append将元素追加到切片的末尾。若它有足够的容量,其目标就会重新切片以容纳新的元素。否则,就会分配一个新的基本数组。append返回更新后的切片,因此必须存储追加后的结果。
输入:

func main() {
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	slice1 := arr[:5]
	fmt.Println(slice1)
	slice2 := append(slice1, 88, 99)
	fmt.Println(slice2)
	//对slice1追加后数值,原切片不影响
	fmt.Println(slice1)
	//追加后赋给原切片!!!(常用)
	slice1 = append(slice1, 88, 99)
	fmt.Println(slice1)
}

输出:

[1 2 3 4 5]
[1 2 3 4 5 88 99]
[1 2 3 4 5]
[1 2 3 4 5 88 99]

切片追加切片
输入:

func main() {
	arr := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	slice1 := arr[:5]
	//追加切片前
	fmt.Println(slice1)
	slice2 := arr[7:]
	slice1 = append(slice1, slice2...)
	//追加切片后
	fmt.Println(slice1)
	slice2[0] = 100
	fmt.Println(slice2)
	//切片slice2的变化,对slice1有影响
	fmt.Println(slice1)
}

输出:

[1 2 3 4 5]
[1 2 3 4 5 8 9 10]
[100 9 10]
[1 2 3 4 5 8 9 100]

切片拷贝
输入:

func main() {
	//切片拷贝
	slice1 := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	slice2 := make([]int, 10)
	copy(slice2, slice1)
	//将slice1拷贝到slice2切片,原理是底层数组的拷贝
	fmt.Println(slice2)
	//验证原理
	slice1[0] = 100
	fmt.Println(slice1) //[100 2 3 4 5 6 7 8 9 10]
	fmt.Println(slice2) //[1 2 3 4 5 6 7 8 9 10]
}

输出:

[1 2 3 4 5 6 7 8 9 10]
[100 2 3 4 5 6 7 8 9 10]
[1 2 3 4 5 6 7 8 9 10]

17.defer
使用defer来延迟一个函数或方法的执行
多个defer按照栈队列的数据结构执行
(1)defer来延迟一个函数–不传参
输入:

// defer关键字使用
func main() {
	print(1)
	print(2)
	defer print(3)
	print(4)
	defer print(5)
	print(6)
	defer print(7)
}
func print(num int) {
	fmt.Println(num)
}

输出:

1
2
4
6
7
5
3

(2)defer来延迟一个函数–传参
输入:

// defer关键字使用
func main() {
	a := 0
	print(a)
	//代码执行到这里,参数已经传进去
	defer print(a)
	a++
	print(a)
}
func print(num int) {
	fmt.Println(num)
}

输出:

0
1
0

18.高级函数
函数本身是一个数据类型
输入:

func main() {
	fmt.Printf("%T", print)
}
func print(num int) {
	fmt.Println(num)
}

输出:

func(int)

因此函数可以定义赋值(引用数据类型)
输入:

func main() {
	fmt.Printf("%T", print1)
	var print2 func(int)
	print2 = print1
	fmt.Println()
	//引用数据类型print2若发生变化,print1同样变化
	fmt.Println(print1)
	fmt.Println(print2)
	print2(1)
}
func print1(num int) {
	fmt.Println(num)
}

输出:

func(int)
0xe6b0e0
0xe6b0e0
1

19.匿名内部类的使用
输入:

func main() {
	//匿名函数1
	f1 := func() {
		fmt.Println("Hello World1")
	}
	f1()
	//匿名函数2
	func() {
		fmt.Println("Hello World2")
	}()
	//匿名函数3(直接调用自己)
	func(a, b int) {
		fmt.Println(a, b)
	}(1, 2)
	//匿名函数4(直接调用自己,带返回类型)
	sum := func(a, b int) int {
		return a + b
	}(1, 2)
	fmt.Println(sum)
}

输出:

Hello World1
Hello World2
1 2
3

20.回调函数
输出:

// 使用回调函数实现加减乘除计算
func main() {

	num1 := oper(10, 3, div)
	fmt.Println(num1)

	//使用匿名函数实现
	num2 := oper(4, 2, func(c float64, d float64) float64 {
		return c / d
	})
	fmt.Println(num2)
}

// 回调函数
func oper(a, b float64, f1 func(float64, float64) float64) float64 {
	return f1(a, b)
}

// 加操作
func add(a, b float64) float64 {
	return a + b
}

// 减操作
func sub(a, b float64) float64 {
	return a - b
}

// 乘操作
func mult(a, b float64) float64 {
	return a * b
}

// 除操作
func div(a, b float64) float64 {
	return a / b
}

输出:

3.3333333333333335
2

21.闭包函数
一个外层函数中,有内层函数,该内层函数中,会操作外层函数的局部变量且该外层函数的返回值就是这个内层函数。这个内层函数和外层函数的局部变量,统称为闭包结构。
当局部变量的生命周期就会发生改变,正常的局部变量会随着函数的调用而创建,随着函数的结束而销毁但是闭包结构中的外层函数的局部变量并不会随着外层函数的结束而销毁,因为内层函数还在继续使用!

输入:

/*
*
一个外层函数中,有内层函数,该内层函数中,会操作外层函数的局部变量且该外层函数的返回值就是这个内层函数。
这个内层函数和外层函数的局部变量,统称为闭包结构
局部变量的生命周期就会发生改变,正常的局部变量会随着函数的调用而创建,随着函数的结束而销毁但是闭包结构中的外层函数的局部变量并不会随着外层函数的结束而销毁,因为内层函数还在继续使用
*/
func main() {
	//调用外部函数oper()返回内部函数
	f2 := oper()
	//执行内部函数,此时i的值为0,i未被销毁!(因为内层函数还在继续使用)
	num1 := f2()
	//输出num1为1
	fmt.Println(num1)
	//此时i的值为1,i仍未被销毁!
	fmt.Println(f2()) //输出2,i仍未被销毁!
	fmt.Println(f2()) //输出3,i仍未被销毁!
	fmt.Println(f2()) //输出4,i仍未被销毁!
	//调用外部函数oper()返回新的内部函数
	f3 := oper()
	num2 := f3()
	fmt.Println(num2)
	//f2()中的i值与f3()中的i值不影响!
	fmt.Println(f2())
	fmt.Println(f3())
}

// 外层函数
func oper() func() int {
	//局部变量
	i := 0
	//内层函数
	f1 := func() int {
		//操作外层函数的局部变量
		i++
		return i
	}
	//外层函数的返回值为内层函数
	return f1
}

输出:

1
2
3
4
1
5
2

22.问题处理recover函数
作用:将程序恢复正常执行,停止恐慌过程。必须与defer函数关联使用。若recover在defer的函数之外被调用,它将不会停止恐慌过程序列。
输入:

func main() {
	test()
	fmt.Println("test()函数执行后。。")
	fmt.Println("已经做出异常处理")
}
func test() {
	//通过匿名函数实现异常的获取与处理
	//一般放在函数的前面,放在后面不起作用
	defer func() {
		//recover() 调用recover函数捕获错误,若没有错误返回nil
		if err := recover(); err != nil {
			fmt.Println("错误信息:", err)
		}
	}()
	a := 10
	b := 0
	fmt.Println(a / b)
}

输出:

错误信息: runtime error: integer divide by zero
test()函数执行后。。
已经做出异常处理

23.自定义异常
使用errors.New(“这是一个自定义异常”)实现自定义异常
输入:

import (
	"errors"
	"fmt"
)

func main() {
	err := zdyError()
	if err != nil {
		fmt.Println(err)
	}
}

func zdyError() error {
	err := errors.New("这是一个自定义异常")
	return err
}

输出:

这是一个自定义异常

24.nil
在Go语言中,nil 是一个预声明的标识符,用来表示某些类型的零值。不同于其他语言中的 null 或 None,nil 在Go中可以用作以下类型的零值:
指针(Pointer):一个未分配到任何对象的指针。
接口(Interface):一个没有绑定任何实现的接口。
切片(Slice):一个没有分配空间的切片。
映射(Map):一个没有分配空间的映射。
通道(Channel):一个未初始化的通道。
函数(Function):一个没有被赋予任何具体实现的函数指针。
25.panic()函数
panic(err) 其中err为error类型
输入:

import (
	"errors"
	"fmt"
)

func main() {
	err := zdyError()
	if err != nil {
		fmt.Println(err)
		panic(err)
	}
	fmt.Println("ok")
}

func zdyError() error {
	err := errors.New("这是一个自定义异常")
	return err
}

输出:

这是一个自定义异常
panic: 这是一个自定义异常

goroutine 1 [running]:
main.main()
	E:/GO/download/WindowsX86/GoWorks/src/project/0608/zidingyiyichang.go:12 +0x7b

26.time的使用
输入:

package main

import (
	"fmt"
	"time"
)
func main() {
	fmt.Println(time.Now().Weekday())
	fmt.Println(time.Now().Year())
	fmt.Println(time.Now().Month())
	fmt.Println(time.Monday)
	fmt.Println(time.Wednesday)
	fmt.Println(time.Weekday(1))
}

输出:

Monday
2024
July
Monday
Wednesday
Monday
  • 28
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值